【转载】图的遍历

【本文是转载的,转载来源: chengyaogen.blog.chinaunix.net 】
 
图的遍历是树的遍历的推广,是按照某种规则(或次序)访问图中各顶点依次且仅一次的操作,亦是将网络结构按某种规则线性化的过程。

 
由于图存在回路,为区别一顶点是否被访问过和避免顶点被多次访问,在遍历过程中,应记下每个访问过的顶点,即每个顶点对应有一个标志位,初始为False,一旦该顶点被访问,就将其置为True,以后若又碰到该顶点时,视其标志的状态,而决定是否对其访问。
 
对图的遍历通常有"深度优先搜索"和"广度优先搜索"方法,二者是人工智能的一个基础。
 
深度优先搜索(Depth First Search,简称DFS)
 
算法思路:
 
类似树的先根遍历。设初始化时,图中各顶点均未被访问,从图中某个顶点(设为V0)出发,访问V0,然后搜索V0的一个邻接点Vi,若Vi未被访问,则访问之,在 搜索Vi的一个邻接点(深度优先)...。若某顶点的邻接点全部访问完毕,则回溯(Backtracking)到它的上一顶点,然后再从此顶点又按深度优先的方法搜索下去,...,直到能访问的顶点都访问完毕为止。
 
设图G10如下图所示:
 
通过深度优先如下:
 
广度优先搜索(Breadth First Search),简称BFS
 
算法思路:
 
类似树的按层次遍历。初始时,图中各顶点均未被访问,从图中某顶点(V0)出发,访问V0,并依次访问V0的各邻接点(广度优先)。然后,分别从这些被访问过的顶点出发,扔仍按照广度优先的策略搜索其它顶点,....,直到能访问的顶点都访问完毕为止。
 
为控制广度优先的正确搜索,要用到队列技术,即访问完一个顶点后,让该顶点的序号进队。然后取相应队头(出队),考察访问过的顶点的各邻接点,将未访问过的邻接点访问 后再依次进队,...,直到队空为止。
 
通过广度优先如下:
 
  1 //下面看一下实现代码:
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5 #define MAX 20
  6 //访问记录
  7 int visit[MAX];
  8 //图的结构设计
  9 typedef struct
 10 {
 11     int vex[MAX];//记录顶点
 12     int adjmatrix[MAX][MAX];//邻接矩阵
 13     int n;//顶点的个数
 14 }GRAPH;
 15 //初始化图
 16 int init_graph(GRAPH *pG)
 17 {
 18     memset(pG,0,sizeof(GRAPH));
 19     pG->n = -1;
 20     printf("input vex\n");
 21     while(scanf("%d",&pG->vex[++pG->n]));
 22     while(getchar() != '\n');
 23 #ifndef _DEBUG_
 24     int i = 0;
 25     for(i = 0;i < pG->n ;i ++)
 26     {
 27         printf("V%d ",pG->vex[i]);
 28     }
 29     printf("\n");    
 30 #endif
 31     
 32     return 0;
 33 }
 34 //获取顶点的位置
 35 int locatevex(GRAPH *pG,int vex)
 36 {
 37     int i = 0;
 38     for(i = 0;i < pG->n;i ++)
 39     {
 40         if(pG->vex[i] == vex )
 41             return i;
 42     }
 43     
 44     return 0;
 45 }
 46 //输入图的顶点之间的边
 47 int input_edge(GRAPH *pG)
 48 {
 49     int vex1,vex2;
 50     int i,j;
 51     printf("input edge(i,j):\n");
 52     //任意字母键结束
 53     while(scanf("(%d,%d)",&vex1,&vex2))
 54     {
 55         getchar();
 56         i = locatevex(pG,vex1);
 57         j = locatevex(pG,vex2);
 58         pG->adjmatrix[i][j] = pG->adjmatrix[j][i] = 1;
 59     }
 60 #ifndef _DEBUG_
 61     int m,n;
 62     for(m = 0;m < pG->n;m ++)
 63     {
 64         for(n = 0;n < pG->n; n ++)
 65         {
 66             printf("%d ",pG->adjmatrix[m][n]);
 67         }
 68         printf("\n");
 69     }
 70 #endif
 71     return 0;
 72 }
 73 //栈的设计
 74 typedef struct
 75 {
 76     int buf[MAX];
 77     int n;
 78 }Stack;
 79 //创建空栈
 80 Stack *create_empty_stack()
 81 {
 82     Stack *stack;
 83     stack = (Stack *)malloc(sizeof(Stack));
 84     stack->n = -1;
 85     return stack;
 86 }
 87 //出栈
 88 int pop_stack(Stack *stack)
 89 {
 90     int temp;
 91     temp = stack->buf[stack->n];
 92     stack->n --;
 93     return temp;
 94 }
 95 //入栈
 96 int push_stack(Stack *stack,int data)
 97 {
 98     stack->n ++;
 99     stack->buf[stack->n] = data;
100     return 0;
101 }
102 //判断空栈
103 int is_empty_stack(Stack *stack)
104 {
105     if(stack->n == -1)
106         return 1;
107     else
108         return 0;
109 }
110 int visit_all(GRAPH *pG)
111 {
112     int i = 0;
113     
114     for(i = 0;i < pG->n; i ++)
115     {
116         if(visit[i] != 1)
117             break;
118     }
119     if(i == pG->n)
120         return 1;
121     else
122         return 0;
123 }
124 //图的深度非递归遍历
125 int DFS(GRAPH *pG,int v)
126 {
127     Stack *stack;
128     int i = 0;
129     
130     stack = create_empty_stack();
131     push_stack(stack,pG->vex[v]);
132     visit[v] = 1;
133     printf("V%d ",pG->vex[v]);
134     
135     while(!is_empty_stack(stack) || !visit_all(pG))
136     {
137         for(i = 0;i < pG->n;i ++)
138         {
139             if(visit[i] == 0 && pG->adjmatrix[v][i] == 1)
140                 break;
141         }
142         if(i == pG->n)
143         {
144             v = pop_stack(stack);
145             
146         }else{
147         
148             v = i;
149             push_stack(stack,pG->vex[v]);
150             visit[v] = 1;
151             printf("V%d ",pG->vex[v]);
152         }
153     }
154     printf("\n");
155     return 0;
156 }
157 //队列的设计
158 typedef struct node
159 {
160     int data;
161     struct node *next;
162     
163 }ListNode;
164 typedef struct
165 {
166     ListNode *front;
167     ListNode *rear;
168 }Queue;
169 //创建空队列
170 Queue *create_empty_queue()
171 {
172     Queue *queue;
173     ListNode *head;
174     queue = (Queue *)malloc(sizeof(Queue));
175     head = (ListNode *)malloc(sizeof(ListNode));
176     queue->front = queue->rear = head;
177     return queue;
178 }
179 //判断队列是否为空
180 int is_empty_queue(Queue *queue)
181 {
182     if(queue->rear == queue->front)
183         return 1;
184     else
185         return 0;
186 }
187 //入队
188 int EnterQueue(Queue *queue,int data)
189 {
190     ListNode *temp;
191     temp = (ListNode *)malloc(sizeof(ListNode));
192     temp->data = data;
193     temp->next = NULL;
194     queue->rear->next = temp;
195     queue->rear = temp;
196     return 0;
197 }
198 //出队
199 int DelQueue(Queue *queue)
200 {
201     ListNode *temp;
202     temp = queue->front;
203     queue->front = queue->front->next;
204     free(temp);
205     temp = NULL;
206     return queue->front->data;
207 }
208 //图的广度遍历
209 int BFS(GRAPH *pG,int v)
210 {
211     Queue *queue = create_empty_queue();
212     int i = 0;
213     
214     memset(&visit,0,sizeof(visit));
215     EnterQueue(queue,v);
216     visit[v] = 1;
217     while(!is_empty_queue(queue))
218     {
219         v = DelQueue(queue);
220         printf("V%d ",pG->vex[v]);
221                 
222         
223         for(i = 0;i < pG->n;i ++)
224         {
225             if(visit[i] == 0 && pG->adjmatrix[v][i] == 1)
226             {
227                 EnterQueue(queue,i);
228                 visit[i] = 1;
229             }
230         }
231     }
232     printf("\n");
233     return 0;
234 }
235 int main()
236 {
237     GRAPH G;
238     int n;
239     //输入顶点,初始化图
240     init_graph(&G);
241     //初始化邻接矩阵
242     input_edge(&G);
243     //图的深度遍历
244     DFS(&G, 0);
245     //图的广度遍历
246     BFS(&G,0);
247     
248     return 0;
249 }

 

 
输出结果:
 
 
posted @ 2013-04-07 13:31  TonyFang  阅读(232)  评论(0编辑  收藏  举报