数据结构 邻接表构造图用来实现DFS算法

全部每周作业和视频思考题答案和解析 见 浙江大学 数据结构 思考题+每周练习答案

虽然我更倾向于使用邻接矩阵来实现图的算法,但是邻接表也不得不用一下,这里整理了一个可以直接运行查看结果的版本:

输入数据: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;
}

输出结果:

发布了174 篇原创文章 · 获赞 394 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tiao_god/article/details/105309395