深度优先搜索(DFS)&广度优先搜索(BFS)
2015-05-20 15:31
471 查看
分类: C/C++
转载请注明来源:http://blog.chinaunix.net/uid-26833883-id-3171290.html
图的遍历是树的遍历的推广,是按照某种规则(或次序)访问图中各顶点依次且仅一次的操作,亦是将网络结构按某种规则线性化的过程。
由于图存在回路,为区别一顶点是否被访问过和避免顶点被多次访问,在遍历过程中,应记下每个访问过的顶点,即每个顶点对应有一个标志位,初始为False,一旦该顶点被访问,就将其置为True,以后若又碰到该顶点时,视其标志的状态,而决定是否对其访问。
对图的遍历通常有"深度优先搜索"和"广度优先搜索"方法,二者是人工智能的一个基础。
深度优先搜索(Depth First Search,简称DFS)
算法思路:
类似树的先根遍历。设初始化时,图中各顶点均未被访问,从图中某个顶点(设为V0)出发,访问V0,然后搜索V0的一个邻接点Vi,若Vi未被访问,则访问之,在 搜索Vi的一个邻接点(深度优先)...。若某顶点的邻接点全部访问完毕,则回溯(Backtracking)到它的上一顶点,然后再从此顶点又按深度优先的方法搜索下去,...,直到能访问的顶点都访问完毕为止。
设图G10如下图所示:
通过深度优先如下:
广度优先搜索(Breadth First Search),简称BFS
算法思路:
类似树的按层次遍历。初始时,图中各顶点均未被访问,从图中某顶点(V0)出发,访问V0,并依次访问V0的各邻接点(广度优先)。然后,分别从这些被访问过的顶点出发,扔仍按照广度优先的策略搜索其它顶点,....,直到能访问的顶点都访问完毕为止。
为控制广度优先的正确搜索,要用到队列技术,即访问完一个顶点后,让该顶点的序号进队。然后取相应队头(出队),考察访问过的顶点的各邻接点,将未访问过的邻接点访问 后再依次进队,...,直到队空为止。
通过广度优先如下:
下面看一下实现代码:
输出结果:
转载请注明来源:http://blog.chinaunix.net/uid-26833883-id-3171290.html
图的遍历是树的遍历的推广,是按照某种规则(或次序)访问图中各顶点依次且仅一次的操作,亦是将网络结构按某种规则线性化的过程。
由于图存在回路,为区别一顶点是否被访问过和避免顶点被多次访问,在遍历过程中,应记下每个访问过的顶点,即每个顶点对应有一个标志位,初始为False,一旦该顶点被访问,就将其置为True,以后若又碰到该顶点时,视其标志的状态,而决定是否对其访问。
对图的遍历通常有"深度优先搜索"和"广度优先搜索"方法,二者是人工智能的一个基础。
深度优先搜索(Depth First Search,简称DFS)
算法思路:
类似树的先根遍历。设初始化时,图中各顶点均未被访问,从图中某个顶点(设为V0)出发,访问V0,然后搜索V0的一个邻接点Vi,若Vi未被访问,则访问之,在 搜索Vi的一个邻接点(深度优先)...。若某顶点的邻接点全部访问完毕,则回溯(Backtracking)到它的上一顶点,然后再从此顶点又按深度优先的方法搜索下去,...,直到能访问的顶点都访问完毕为止。
设图G10如下图所示:
通过深度优先如下:
广度优先搜索(Breadth First Search),简称BFS
算法思路:
类似树的按层次遍历。初始时,图中各顶点均未被访问,从图中某顶点(V0)出发,访问V0,并依次访问V0的各邻接点(广度优先)。然后,分别从这些被访问过的顶点出发,扔仍按照广度优先的策略搜索其它顶点,....,直到能访问的顶点都访问完毕为止。
为控制广度优先的正确搜索,要用到队列技术,即访问完一个顶点后,让该顶点的序号进队。然后取相应队头(出队),考察访问过的顶点的各邻接点,将未访问过的邻接点访问 后再依次进队,...,直到队空为止。
通过广度优先如下:
下面看一下实现代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 20 //访问记录 int visit[MAX]; //图的结构设计 typedef struct { int vex[MAX];//记录顶点 int adjmatrix[MAX][MAX];//邻接矩阵 int n;//顶点的个数 }GRAPH; //初始化图 int init_graph(GRAPH *pG) { memset(pG,0,sizeof(GRAPH)); pG->n = -1; printf("input vex\n"); while(scanf("%d",&pG->vex[++pG->n])); while(getchar() != '\n'); #ifndef _DEBUG_ int i = 0; for(i = 0;i < pG->n ;i ++) { printf("V%d ",pG->vex[i]); } printf("\n"); #endif return 0; } //获取顶点的位置 int locatevex(GRAPH *pG,int vex) { int i = 0; for(i = 0;i < pG->n;i ++) { if(pG->vex[i] == vex ) return i; } return 0; } //输入图的顶点之间的边 int input_edge(GRAPH *pG) { int vex1,vex2; int i,j; printf("input edge(i,j):\n"); //任意字母键结束 while(scanf("(%d,%d)",&vex1,&vex2)) { getchar(); i = locatevex(pG,vex1); j = locatevex(pG,vex2); pG->adjmatrix[i][j] = pG->adjmatrix[j][i] = 1; } #ifndef _DEBUG_ int m,n; for(m = 0;m < pG->n;m ++) { for(n = 0;n < pG->n; n ++) { printf("%d ",pG->adjmatrix[m] ); } printf("\n"); } #endif return 0; } //栈的设计 typedef struct { int buf[MAX]; int n; }Stack; //创建空栈 Stack *create_empty_stack() { Stack *stack; stack = (Stack *)malloc(sizeof(Stack)); stack->n = -1; return stack; } //出栈 int pop_stack(Stack *stack) { int temp; temp = stack->buf[stack->n]; stack->n --; return temp; } //入栈 int push_stack(Stack *stack,int data) { stack->n ++; stack->buf[stack->n] = data; return 0; } //判断空栈 int is_empty_stack(Stack *stack) { if(stack->n == -1) return 1; else return 0; } int visit_all(GRAPH *pG) { int i = 0; for(i = 0;i < pG->n; i ++) { if(visit[i] != 1) break; } if(i == pG->n) return 1; else return 0; } //图的深度非递归遍历 int DFS(GRAPH *pG,int v) { Stack *stack; int i = 0; stack = create_empty_stack(); push_stack(stack,pG->vex[v]); visit[v] = 1; printf("V%d ",pG->vex[v]); while(!is_empty_stack(stack) || !visit_all(pG)) { for(i = 0;i < pG->n;i ++) { if(visit[i] == 0 && pG->adjmatrix[v][i] == 1) break; } if(i == pG->n) { v = pop_stack(stack); }else{ v = i; push_stack(stack,pG->vex[v]); visit[v] = 1; printf("V%d ",pG->vex[v]); } } printf("\n"); return 0; } //队列的设计 typedef struct node { int data; struct node *next; }ListNode; typedef struct { ListNode *front; ListNode *rear; }Queue; //创建空队列 Queue *create_empty_queue() { Queue *queue; ListNode *head; queue = (Queue *)malloc(sizeof(Queue)); head = (ListNode *)malloc(sizeof(ListNode)); queue->front = queue->rear = head; return queue; } //判断队列是否为空 int is_empty_queue(Queue *queue) { if(queue->rear == queue->front) return 1; else return 0; } //入队 int EnterQueue(Queue *queue,int data) { ListNode *temp; temp = (ListNode *)malloc(sizeof(ListNode)); temp->data = data; temp->next = NULL; queue->rear->next = temp; queue->rear = temp; return 0; } //出队 int DelQueue(Queue *queue) { ListNode *temp; temp = queue->front; queue->front = queue->front->next; free(temp); temp = NULL; return queue->front->data; } //图的广度遍历 int BFS(GRAPH *pG,int v) { Queue *queue = create_empty_queue(); int i = 0; memset(&visit,0,sizeof(visit)); EnterQueue(queue,v); visit[v] = 1; while(!is_empty_queue(queue)) { v = DelQueue(queue); printf("V%d ",pG->vex[v]); for(i = 0;i < pG->n;i ++) { if(visit[i] == 0 && pG->adjmatrix[v][i] == 1) { EnterQueue(queue,i); visit[i] = 1; } } } printf("\n"); return 0; } int main() { GRAPH G; int n; //输入顶点,初始化图 init_graph(&G); //初始化邻接矩阵 input_edge(&G); //图的深度遍历 DFS(&G, 0); //图的广度遍历 BFS(&G,0); return 0; }
输出结果:
相关文章推荐
- leetcode:深度优先搜索(DFS)和广度优先搜索(BFS)
- BFS(广度优先搜索) 和 DFS(深度优先搜索)
- 算法: 无向图的深度优先搜索(dfs)和广度优先搜索(bfs)
- 二叉树 深度优先搜索(DFS)、广度优先搜索(BFS)
- 简单DFS(深度优先搜索)和BFS(广度优先搜索)学习积累
- DFS(深度优先搜索)___BFS(广度优先搜索)过程图解
- 图的深度优先搜索(DFS)、广度优先搜索(BFS)
- 深度优先搜索(DFS),广度优先搜索(BFS)
- Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)
- 关于图的广度优先搜索(BFS)和深度优先搜索(DFS)
- 深度优先搜索(DFS)与广度优先搜索(BFS)简单实现
- HDU 1241 Oil Deposits DFS(深度优先搜索) 和 BFS(广度优先搜索)
- 图(邻接表)的遍历——DFS(深度优先搜索)和BFS(广度优先搜索)和连通图
- [Python Data Structure] 广度优先搜索(BFS)和深度优先搜索(DFS)
- 图的深度优先搜索(DFS)和广度优先搜索(BFS)
- 深度优先搜索(DFS)与广度优先搜索(BFS)
- HDU 1312 Red and Black DFS(深度优先搜索) 和 BFS(广度优先搜索)
- 图的深度优先搜索(DFS),广度优先搜索(BFS)与最小生成树(MST)
- DFS(深度优先搜索)与BFS(广度优先搜索)
- HDU 4707 Pet(DFS(深度优先搜索)+BFS(广度优先搜索))