用邻接表表示图进行深度优先遍历时,通常采用()来实现算法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用邻接表表示图进行深度优先遍历时,通常采用()来实现算法相关的知识,希望对你有一定的参考价值。
使用栈来实现算法。
用邻接表表示图进行深度优先遍历时,通常采用栈来实现算法,广度遍历使用队列。
扩展材料:
深度优先遍历:类似与树的前序遍历。从图中的某个顶点v出发,访问此顶点,然后从v的未被访问到的邻接点进行遍历,直到图中所有和v有路径相通的顶点都被访问到
注:优先访问外层节点,访问到无新顶点时,会进行回退,访问未被访问过的分支顶点。
广度优先遍历:类似于树的层序遍历。从图中的某个顶点w出发,让顶点w入队,然后顶点w再出队,并让所有和顶点w相连的顶点入队,然后再出队一个顶点t,并让所有和t相连但未被访问过的顶点入队……由此循环,指定图中所有元素都出队。
参考资料来源:
知网论文-数据结构中图的遍历算法研究
用邻接表表示图进行深度优先遍历时,通常采用栈来实现算法。
邻接表,存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。
对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
邻接表相似类:
图的邻接表存储方法跟树的孩子链表示法相类似,是一种顺序分配和链式分配相结合的存储结构。如这个表头结点所对应的顶点存在相邻顶点,则把相邻顶点依次存放于表头结点所指向的单向链表中。如词条概念图所示,表结点存放的是邻接顶点在数组中的索引。对于无向图来说,使用邻接表进行存储也会出现数据冗余,表头结点A所指链表中存在一个指向C的表结点的同时,表头结点C所指链表也会存在一个指向A的表结点。
邻接表是图的一种最主要存储结构,用来描述图上的每一个点。对图的每个顶点建立一个容器(n个顶点建立n个容器),第i个容器中的结点包含顶点Vi的所有邻接顶点。实际上我们常用的邻接矩阵就是一种未离散化每个点的边集的邻接表。
参考技术B 邻接表图的深度优先,思想是以深度因素为优先遍历,(因此可以检测是否图为连通图),可以想像成你从上往下走迷宫,走不动了就从根再换条路走,算法实现方式就与这种思想匹配,使用递归(栈)来完成遍历。具体为:void DfsTra(graph t,bool visit[n])
int i;//n为图的顶点个数,visit数组最好全局化
for(i=0;i<n;i++)visit[i]=false;
//访问数组
for(i=0;i<n;i++)
if(!visit[i])DFS(G,i);
//对每个未访问顶点调用DFS
邻接表结构
头结点为data和firstarc(指向第一个相连结点)
表结点为adjvex(出度顶点序号)和info和nextarc(指向下一个与头结点相连结点)
void DFS(graph G,int i)
visit[i]=true;//visit(i);
for(w=firstarcadjvex(G,i);w>=0;w=nextarcadjvex(G,i,w))//重点代码,w等于第一个相连结点的adjvex,一直往后到最后一个相连结点的adjvex
if(!visit[w])DFS(G,w);
//递归思想,不停调用自身,但是始终是以深度为优先
参考技术C 用邻接表表示图进行深度优先遍历时,通常采用(栈 )来实现算法
图的邻接表存储表示,图的深度优先和广度优先遍历
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 }
以上是关于用邻接表表示图进行深度优先遍历时,通常采用()来实现算法的主要内容,如果未能解决你的问题,请参考以下文章
用邻接表表示图的广度优先搜索时的存储结构,通常采用()结构来实现算法
用邻接表表示图的广度优先搜索时的存储结构,通常采用()结构来实现算法