图的邻接表存储表示,图的深度优先和广度优先遍历

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3
  4 #define MAX_VERTAX_SIZE 20
  5 #define OK 1
  6 #define ERROR 0
  7
  8 typedef int Status;
  9 typedef char ElemType;
 10
 11 typedef struct EageNode{
 12     int adjacentVertax;
 13     struct EageNode* nextAdjacentVertax;
 14 }EageNode, *EageNodePtr;
 15
 16 typedef struct VertaxNode{
 17     ElemType data;
 18     EageNodePtr firstEage;
 19 }VertaxNode;
 20
 21 typedef struct GraphAL{
 22     VertaxNode VertaxArray[MAX_VERTAX_SIZE];
 23     int vertaxNum;
 24     int eageNum;
 25 }GraphAL;
 26
 27 //定义队列结构,用于图的广度优先遍历
 28 typedef struct QueueNode{
 29     ElemType data;
 30     struct QueueNode* next;
 31 }QueueNode, *QueueNodePtr;
 32 typedef struct Queue{
 33     QueueNodePtr front;
 34     QueueNodePtr rear;
 35 }Queue;
 36 Status InitQueue(Queue* Q){
 37     Q->front = (QueueNodePtr)malloc(sizeof(struct QueueNode));
 38     if( !Q->front )
 39         return ERROR;
 40     Q->rear = Q->front;
 41     Q->rear->next = NULL;
 42     return OK;
 43 }
 44 Status EnterQueue(Queue *q, ElemType value){
 45     QueueNode* n;
 46     n = (QueueNode*)malloc(sizeof(struct QueueNode));
 47     if( !n )
 48         return ERROR;
 49     n->data = value;
 50     n->next = q->rear->next;
 51     q->rear->next = n;
 52     q->rear = n;
 53     return OK;
 54 }
 55 Status DeleteQueue(Queue* q,ElemType* value){
 56     if( q->front == q->rear )
 57         return ERROR;
 58     QueueNode* p;
 59     p = q->front->next;
 60     *value = p->data;
 61     q->front->next = p->next;
 62     free(p);
 63     if( p == q->rear )
 64         q->rear = q->front;
 65     return OK;
 66 }
 67 int IsQueueEmpty(Queue q){
 68     return q.front == q.rear ? OK : ERROR;
 69 }
 70 /*
 71 int main(){
 72     Queue q;
 73     ElemType c;
 74     InitQueue(&q);
 75     EnterQueue(&q,‘a‘);
 76     EnterQueue(&q,‘f‘);
 77     EnterQueue(&q,‘g‘);
 78     EnterQueue(&q,‘e‘);
 79     DeleteQueue(&q,&c);
 80     printf("%c \n", c);
 81     printf("&&&&%d", IsQueueEmpty(q));
 82     DeleteQueue(&q,&c);
 83     printf("%c \n", c);
 84     return 0;
 85 }
 86 */
 87
 88 //返回顶点v在G中的下标
 89 int LocateVertax(GraphAL G, ElemType v){
 90     int i;
 91     for( i = 0; i < G.vertaxNum; i++ ){
 92         if( G.VertaxArray[i].data == v )
 93             return i;
 94     }
 95     return -1;
 96 }
 97 //通过下标得到元素的值
 98 ElemType GetValueFromIndex(GraphAL G, int index){
 99     return G.VertaxArray[index].data;
100 }
101 //创建邻接表无向图
102 Status CreateUDG_AdjacencyList(GraphAL* G){
103     int i;
104     ElemType v,w;
105     int index_v, index_w;
106     EageNodePtr vPtr,wPtr;
107     printf("    Create Undigraph\n");
108     printf("Please enter the number of Vertax and Eage: ");
109     scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));
110
111     printf("ok, please input the value of %d Vertax\n", G->vertaxNum);
112     for( i = 0; i < G->vertaxNum; i++ ){
113         scanf("%c%*c", &(G->VertaxArray[i].data));
114         G->VertaxArray[i].firstEage = NULL;
115     }
116
117     for( i = 0; i < G->eageNum; i++ ){
118         printf("ok, please input the two Vertax of Eage %d (Sepearted by Space) :", i+1);
119         scanf("%c %c%*c", &v,&w);    //一条边的两个顶点v w
120         index_v = LocateVertax(*G, v);
121         index_w = LocateVertax(*G, w);
122         wPtr = (EageNode*)malloc(sizeof(EageNode));
123         if( !wPtr )
124             return ERROR;
125         wPtr->adjacentVertax = index_w;
126         wPtr->nextAdjacentVertax = G->VertaxArray[index_v].firstEage;
127         G->VertaxArray[index_v].firstEage = wPtr;
128
129         vPtr = (EageNode*)malloc(sizeof(EageNode));
130         if( !vPtr )
131             return ERROR;
132         vPtr->adjacentVertax = index_v;
133         vPtr->nextAdjacentVertax = G->VertaxArray[index_w].firstEage;
134         G->VertaxArray[index_w].firstEage = vPtr;
135     }
136     return OK;
137 }
138 //在图G中找v的第一个邻接顶点,找到则返回该顶点在邻接表中的位置,若没有则返回-1
139 int FirstAdjacentVertax(GraphAL G, ElemType v){
140     int index_v;
141     index_v = LocateVertax(G, v);
142     if( G.VertaxArray[index_v].firstEage == NULL )
143         return -1;
144     else
145         return (G.VertaxArray[index_v].firstEage)->adjacentVertax;
146 }
147 //在图G中找v的从w开始的下一个相邻的顶点
148 int NextAdjacentVertax(GraphAL G, ElemType v, ElemType w ){
149     int index_v,index_w;
150     EageNodePtr p;
151     index_v = LocateVertax(G, v);
152     index_w = LocateVertax(G, w);
153     if( G.VertaxArray[index_v].firstEage == NULL )
154         return -1;
155     p = G.VertaxArray[index_v].firstEage;         //p pointer to first node
156     while( p->nextAdjacentVertax != NULL ){
157         if( p->adjacentVertax == index_w )
158             return p->nextAdjacentVertax->adjacentVertax;
159         p = p->nextAdjacentVertax;
160     }
161     return -1;
162 }
163
164 //DFS深度优先遍历图:使用递归算法,算法思想:
165 //        1:从v顶点开始,visit(v),将其设置为已遍历
166 //        2: 获得v的第一个邻接顶点w,若其存在并且没有访问过,递归遍历;
167 //        3: 获得v的从w之后的邻接点,若其存在并且没有访问过,递归遍历;直到所有都访问过
168 int visitedArray[MAX_VERTAX_SIZE];
169 void visit(ElemType c){
170     printf("%c ", c);
171 }
172 Status DFS(GraphAL G, ElemType v){
173     ElemType w;
174     visit(v);
175     visitedArray[LocateVertax(G, v)] = 1;
176     for( w = GetValueFromIndex(G, FirstAdjacentVertax(G, v)); LocateVertax(G, w) != -1; w = GetValueFromIndex(G, NextAdjacentVertax(G, v, w))){
177         if( visitedArray[LocateVertax(G, w)] != 1 )
178             DFS(G, w);
179     }
180     return OK;
181 }
182 Status DFSTraverse(GraphAL G){
183     int i;
184     for( i = 0; i < G.vertaxNum; i++ )
185         visitedArray[i] = 0;
186     for( i = 0; i < G.vertaxNum; i++ )
187         if( visitedArray[i] != 1 )
188             DFS(G, GetValueFromIndex(G, i));
189     return OK;
190 }
191
192
193 //BFS(Breadth First Search)
194 Status BFS(GraphAL G){
195     int i,j;
196     Queue q;
197     ElemType c;
198     InitQueue(&q);
199     for(i = 0; i < G.vertaxNum; i++)
200         visitedArray[i] = 0;
201     for(i = 0; i < G.vertaxNum; i++){    //这个for实际执行的次数是连通分量的个数
202         if( visitedArray[i] == 0 ){
203             EnterQueue(&q, G.VertaxArray[i].data);
204             visitedArray[i] = 1;
205             while( IsQueueEmpty(q) != OK ){
206                 DeleteQueue(&q, &c);
207                 visit(c);
208                 for( j = FirstAdjacentVertax(G, c); j != -1; j = NextAdjacentVertax(G, c, GetValueFromIndex(G, j))){
209                     if( visitedArray[j] == 0 ){
210                         EnterQueue(&q, GetValueFromIndex(G, j));
211                         visitedArray[j] = 1;
212                     }
213                 }
214             }
215         }
216     }
217 }
218
219
220 //打印无向图的邻接表
221 void PrintUDG_AdjacentList(GraphAL G){
222     int i;
223     EageNodePtr p;
224     printf("  Adjacency List \n");
225     for( i = 0; i < G.vertaxNum; i++ ){
226         printf(" %d %c ",i, G.VertaxArray[i]);
227         p = G.VertaxArray[i].firstEage;
228         while( p != NULL ){
229             printf("-->%d", p->adjacentVertax);
230             p = p->nextAdjacentVertax;
231         }
232         printf("\n");
233     }
234 }
235 int main(){
236     GraphAL G;
237     CreateUDG_AdjacencyList(&G);
238     PrintUDG_AdjacentList(G);
239
240     printf("   DFS(Depth First Search) of UDG(Undigraph)\n");
241     DFSTraverse(G);
242
243     printf("\n  BFS(Breadth First Search) of UDG(Undigraph)\n");
244     BFS(G);
245     return 0;
246 }

时间: 2024-12-06 16:55:48

图的邻接表存储表示,图的深度优先和广度优先遍历的相关文章

数据结构之---C语言实现图的邻接表存储表示

// 图的数组(邻接矩阵)存储表示 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME 3 // 顶点字符串的最大长度+1 #define MAX_VERTEX_NUM 20 typedef int InfoType; // 存放网的权值 typedef char VertexType[MAX_NAME]; // 字符串类型 typedef enum{DG, DN, AG

数据结构实践——操作用邻接表存储的图

本文是针对[数据结构基础系列(7):图]的实践. [项目 - 操作用邻接表存储的图] 假设图G采用邻接表存储,分别设计实现以下要求的算法: (1)输出出图G中每个顶点的出度: (2)求出图G中出度最大的一个顶点,输出该顶点编号: (3)计算图G中出度为0的顶点数: (4)判断图G中是否存在边<i,j>. 利用下图作为测试用图,输出结果. 提示:(1)分别设计函数实现算法:(2)不要全部实现完再测试,而是实现一个,测试一个:(3)请利用图算法库. [参考解答] #include <stdi

数据结构(10) -- 图的邻接表存储

////////////////////////////////////////////////////////// //图的邻接表存储 ////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> using namespace std; //图的邻接表表示法 #define MaxVertexNum 100 enum GraphType{DG,

图的邻接表存储方式的建立

图的邻接表存储方式,主要由表节点与头结点组成. 头结点中主要包含两个域: 1)存放顶点信息 2)存放与顶点相连的第一个表节点的指针 表节点中主要包含两个域: 1)存放相连的节点的序号 2)指向下一个节点的指针 #define MAXNUM 100; //表节点 typedef struct ArcNode{ int adjvex;//邻接顶点编号 struct ArcNode *next;//下一邻接顶点 }ArcNode; //头结点 typedef struct AdjList{ char

图的邻接表存储

图的邻接表存储 struct Edge { int v; ll w; Edge *next; };Edge e[maxn*10]; void add_edge(int u,int v,ll w) ///插入邻接表的首部而非尾部,避免遍历 { Edge *pre=&e[u]; Edge *p=(Edge*)malloc(sizeof(Edge)); p->v=v;p->w=w; p->next=pre->next; pre->next=p; } //遍历 for(Edg

_DataStructure_C_Impl:图的邻接表存储

#include<stdio.h> #include<stdlib.h> #include<string.h> //图的邻接表类型定义 typedef char VertexType[4]; typedef char InfoPtr; typedef int VRType; #define INFINITY 10000 //定义一个无限大的值 #define MaxSize 50 //最大顶点个数 typedef enum{DG,DN,UG,UN}GraphKind;

图的邻接表存储c实现(DFS遍历)

先简要列出实现过程中所需要的数据结构. 如下图 对于这个图而言,它的邻接表可以这样表示,当然表现形式可以多样,这只是我随便画的一种表示方法. 顶点表                                          边表 我们把第一个表即上面标着fixedvex的这个表称作顶点表,后边的称为边表. 上图所示,边表的结构应该这样写: //定义一个边表节点的结构 typedef struct node{ int adjvex; //int Mark; //用于标记是否被访问过 nod

基于邻接表存储的图的深度优先遍历和广度优先遍历

一.深度优先遍历是连通图的一种遍历策略.其基本思想如下: 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y).若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过:然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边.上述过程直至从x出发的所有边都已检测过为止. 例如下图中: 1.从0开始,首先找到0的关

数据结构(11) -- 邻接表存储图的DFS和BFS

/////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS /////////////////////////////////////////////////////////////// #include <iostream> #include <stdlib.h> #include <queue> using namespace std; //图的邻接表表示法