您的位置:首页 > 其它

图的深度优先搜索和广度优先搜索

2015-09-21 16:26 225 查看
深度优先搜索首先访问起始顶点v,这里假设访问只是输出结点所对应的顶点序号字段,然后,从顶点v的邻接表中选取一个未访问过的顶点w进行访问,并从w开始继续进行深度优先搜索,将v的邻接表中的当前位置保存在一个栈中,当最终搜索到一个顶点u,且u的邻接表中的顶点全部被访问过时,就从栈中取出一个顶点,并按照上述方法处理该顶点的邻接表,整个过程类似树的前序遍历。

图G的结构图和邻接表图:







其图深度搜索访问次序:v0,v1,v3,v7,v4,v5,v2,v6.

代码实现

#include <iostream>
#define FALSE 0
#define TRUE 1
#include<stdio.h>
//结点
typedef struct node
{
   int value;
   struct node * next;
}edgenode;
//无向图链表的头结点
typedef struct vnode
{
   int value;//无向图链表的头结点索引
   edgenode* firstedgenode;//指向该顶点的第一个相邻结点
}topnode;
//无向图指向链表链的数组
typedef topnode node_list[MAX+1];
//无向图的结构体
typedef struct linklist_graph
{
   int nodes,edges;//无向图的结点数和边数
   node_list linklist;//无向图的指向链表链的数组
}linkgraph;
void dfs(int v)
{
   edgenode* w;
   visited[v]=TRUE;
   printf("%5d",v);
   for(w=linkgraph.linklist[v].firstedgenode;w;w=w->next)
      if(!visited[w->value])
         dfs(w->value);
}


广度优先搜索从顶点v开始,并把v标记为”已访问”,然后,访问v的邻接表中的每一个顶点,在访问过v的邻接表中的所有顶点以后,访问与v的邻接表中的第一个顶点相邻,且未访问的所有顶点,为了实现这种策略,把当前访问的顶点保存在一个队列中,在当前顶点的邻接表中的所有顶点被访问过以后,从队列中取出一个顶点,然后访问该顶点的邻接表中的所有顶点,在搜索过程中,未被访问过的顶点被访问,且存入队列,已经访问过的顶点不在被访问,当队列为空时,搜索结,类似树的层次遍历。

上面图的广度优先搜索顺序:v0,v1,v2,v3,v4,v5,v6,v7

代码实现:

typedef struct queue *queue_pointer;
//动态链式队列
typedef struct queue
{
   int index;
   queue_pointer link;
};
void bfs(int v)
{
   edgenode* w;
   queue_pointer front,rear;
   front=rear=NULL;
   printf("%5d",v);
   addq(&front,&rear,v);
   while(front)
   {
      v=delete(&front);
      for(w=linkgraph.linklist[v].firstedgenode;w;w=w->next)
         if(!visited[w->value])
         {
               printf("%5d",w->value);
               addq(&front,&rear,w->value);
               visited[w->value]=TRUE;
         }
   }
}


上面两种算法,对图的邻接表来说,其扫描全部边的时间复杂度为O(e),而如果是图的邻接矩阵,其扫描全部边的时间复杂度为O(n2n^2).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: