14:39:22 2019-09-01
学习
图的两种遍历方法:
①DFS 深度优先搜索(Depth First Search)
②BFS 广度优先搜索(Breadth First Search) //利用队列实现广度优先
//邻接表实现 及 利用 邻接表 实现 深度优先搜索(DFS)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<malloc.h> 4 //表示图的两种方法 5 //邻接矩阵 G[N][N] N个顶点从0到N-1编号 6 //邻接表 表示 7 /*Graph Create(); //建立并返回空图 8 Graph InsertVertex(Graph G, Vertex v); //将v插入G 9 Graph InsertEdge(Graph G, Edge e); //将e插入G 10 void DFS(Graph G, Vertex v); //从顶点v出发深度优先遍历图G 11 void BFS(Graph G, Vertex v); //从顶点v出发宽度优先遍历图G 12 void ShortestPath(Graph G, Vertex v, int Dist[]); //计算图G中顶点v到任意其它顶点的最短距离 13 void MST(Graph G); //计算图G的最小生成树*/ 14 15 //图的邻接表表示法 16 #define MaxVerterNum 100 //最大顶点数 17 #define INFINITY 65535 // 18 typedef int Vertex; //顶点下标表示顶点 19 typedef int WeightType; //边的权值 20 typedef char DataType; //顶点存储的数据类型 21 22 //边的定义 23 typedef struct ENode* PtrToENode; 24 typedef PtrToENode Edge; 25 struct ENode 26 { 27 Vertex V1, V2; //有向边<V1,V2> 28 WeightType Weight; //权重 29 }; 30 31 //邻接点的定义 32 typedef struct AdjVNode* PtrToAdjVNode; 33 struct AdjVNode 34 { 35 Vertex AdjV; //邻接点下标 36 WeightType Weight; //边权重 37 PtrToAdjVNode Next; //指向下一个邻接点的指针 38 }; 39 40 //顶点表头节点的定义 41 typedef struct Vnode 42 { 43 PtrToAdjVNode FirstEdge; //边表头指针 44 DataType Data; //存顶点的数据 45 }AdjList[MaxVerterNum]; //AdjList是邻接表类型 46 47 //图节点的定义 48 typedef struct GNode* PtrToGNode; 49 typedef PtrToGNode LGraph; 50 struct GNode 51 { 52 int Nv; //顶点数 53 int Ne; //边数 54 AdjList G; //邻接表 55 }; 56 57 LGraph CreateGraph(int VertexNum) 58 {//初始化一个有VertexNum个顶点但没有边的图 59 Vertex V; 60 LGraph Graph; 61 62 Graph = (LGraph)malloc(sizeof(struct GNode)); //建立图 63 Graph->Nv = VertexNum; 64 Graph->Ne = 0; 65 //初始化邻接表头指针 66 for (V = 0; V < Graph->Nv; V++) 67 Graph->G[V].FirstEdge = NULL; 68 return Graph; 69 } 70 71 void InsertEdge(LGraph Graph, Edge E) 72 { 73 PtrToAdjVNode NewNode; 74 //插入边<V1,V2> 75 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); 76 NewNode->AdjV = E->V2; 77 NewNode->Weight = E->Weight; 78 NewNode->Next = Graph->G[E->V1].FirstEdge; 79 Graph->G[E->V1].FirstEdge = NewNode; 80 81 //若是无向图 还要插入边<V2,V1> 82 NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); 83 NewNode->AdjV = E->V1; 84 NewNode->Weight = E->Weight; 85 NewNode->Next = Graph->G[E->V2].FirstEdge; 86 Graph->G[E->V2].FirstEdge = NewNode; 87 } 88 89 LGraph BuildGraph() 90 { 91 LGraph Graph; 92 Edge E; 93 Vertex V; 94 int Nv, i; 95 96 scanf("%d", &Nv); /* 读入顶点个数 */ 97 Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */ 98 scanf("%d", &(Graph->Ne)); //读入边数 99 if (Graph->Ne != 0) 100 { 101 E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */ 102 /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */ 103 for (i = 0; i < Graph->Ne; i++) 104 { 105 scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); 106 InsertEdge(Graph, E); 107 } 108 } 109 /* 如果顶点有数据的话,读入数据 */ 110 for (V = 0; V < Graph->Nv; V++) 111 scanf(" %c", &(Graph->G[V].Data)); 112 return Graph; 113 } 114 115 //DFS 利用邻接表存储的图 实现 深度优先搜索 116 int visited[100]; 117 void Visit(Vertex V) 118 { 119 printf("访问顶点%d\n", V); 120 } 121 122 // visited[]是全局变量 初始化为0 123 void DFS(LGraph Graph, Vertex V) //以V为出发点访对邻接表存储的图进行DFS访问 124 { 125 Visit(V); 126 visited[V] = 1; 127 128 PtrToAdjVNode W; //用来从某个点 出发访问 129 for (W = Graph->G[V].FirstEdge; W; W = W->Next) 130 { 131 if (!visited[W->AdjV]) //若 W->Adjv未被访问 则递归访问 132 DFS(Graph, W->AdjV); 133 } 134 }