全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案
虽然我更倾向于使用邻接矩阵来实现图的算法,但是邻接表也不得不用一下,这里整理了一个可以直接运行查看结果的版本:
输入数据:4 5为顶点数和边数,然后是5行数据,每行前两个代表边的顶点索引,第三个代表边的权重
4 5
0 1 1
1 3 2
0 3 4
0 2 2
2 3 1
函数列表:
GGraph* CreateGraph(int VertexNum) 创建一个图
void InsertEdge(GGraph* Graph, Edge* E) 往图中插入一条边
GGraph* BuildGraph() 建立图
void initGraphdata(GGraph* Graph) 初始化图
void DFS(GGraph* Graph, int V) DFS遍历图
测试程序:
#include <iostream>
using namespace std;
#define MaxVertexNum 100
int Visited[MaxVertexNum];
// 边的定义
struct Edge {
int V1, V2; // 有向边<V1, V2>
int Weight; // 权重
};
// 邻接点的定义
struct AdjVNode {
int AdjV; // 邻接点下标
int Weight; // 边权重
AdjVNode * Next; // 指向下一个邻接点的指针
};
// 顶点表头结点的定义
typedef struct Vnode {
AdjVNode* FirstEdge;// 边表头指针
char Data; // 存顶点数据,一般是没有用的
// 注意:很多情况下,顶点无数据,此时Data可以不用出现
} AdjList[MaxVertexNum]; // AdjList是邻接表类型
struct GGraph {
int Nv; // 顶点数
int Ne; // 边数
AdjList G; // 邻接表
};
GGraph* CreateGraph(int VertexNum)
{ // 初始化一个有VertexNum个顶点但没有边的图
GGraph* Graph;
Graph = (GGraph*)malloc(sizeof(struct GGraph)); // 建立图
Graph->Nv = VertexNum;
Graph->Ne = 0;
// 初始化邻接表头指针
// 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1)
for (int V = 0; V<Graph->Nv; V++)
Graph->G[V].FirstEdge = NULL;
return Graph;
}
void InsertEdge(GGraph* Graph, Edge* E)
{
AdjVNode * NewNode;
// 插入边 <V1, V2>
// 为V2建立新的邻接点
NewNode = (AdjVNode *)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = E->V2;
NewNode->Weight = E->Weight;
// 将V2插入V1的表头
NewNode->Next = Graph->G[E->V1].FirstEdge;
Graph->G[E->V1].FirstEdge = NewNode;
// 若是无向图,还要插入边 <V2, V1>
// 为V1建立新的邻接点
NewNode = (AdjVNode *)malloc(sizeof(struct AdjVNode));
NewNode->AdjV = E->V1;
NewNode->Weight = E->Weight;
// 将V1插入V2的表头
NewNode->Next = Graph->G[E->V2].FirstEdge;
Graph->G[E->V2].FirstEdge = NewNode;
}
GGraph* BuildGraph()
{
GGraph* Graph;
Edge* E;
int Nv;
cin>>Nv; // 读入顶点个数
Graph = CreateGraph(Nv); // 初始化有Nv个顶点但没有边的图
cin >>Graph->Ne; // 读入边数
if (Graph->Ne != 0) { // 如果有边
E = (Edge*)malloc(sizeof(struct Edge)); // 建立边结点
// 读入边,格式为"起点 终点 权重",插入邻接矩阵
for (int i = 0; i<Graph->Ne; i++) {
cin >> E->V1 >> E->V2 >> E->Weight;
// 注意:如果权重不是整型,Weight的读入格式要改
InsertEdge(Graph, E);
}
}
// 如果顶点有数据的话,读入数据
return Graph;
}
void initGraphdata(GGraph* Graph) {
//初始化Visited
for (int V = 0; V<Graph->Nv; V++)
Visited[V] = 0;
}
void DFS(GGraph* Graph, int V)
{ // 以V为出发点对邻接表存储的图Graph进行DFS搜索
AdjVNode * W;
cout<< V <<endl; // 访问第V个顶点
Visited[V] = true; // 标记V已访问
for (W = Graph->G[V].FirstEdge; W; W = W->Next) // 对V的每个邻接点W->AdjV
if (!Visited[W->AdjV]) // 若W->AdjV未被访问
DFS(Graph, W->AdjV); // 则递归访问之
}
int main(void) {
GGraph* myGraph = BuildGraph();
initGraphdata(myGraph);
DFS(myGraph,0);
system("pause");
return 0;
}
输出结果: