图的深度优先遍历(DFS)&广度优先遍历(BFS)

深度优先搜索遍历类似于树的先序遍历(根节点→左子树→右子树),借助了结构以实现递归

广度优先搜索遍历则类似于层次遍历,借助于队列结构实现。

因为图的任意两个顶点都有可能存在联系,所以在访问某个顶点后,可能沿着某条路径又会回到访问过的顶点。为了避免同一顶点被访问多次,在遍历图的过程中,必须用一个数组visited[]记录每个访问过的顶点。

邻接矩阵为存储结构的遍历,时间复杂度为O(n²);以邻接表为存储结构的遍历,时间复杂度为O(n+e)

 

目录

一.深度优先遍历(DFS)

1.DFS定义

2.递归实现DFS

邻接矩阵:

邻接表:

3.非递归实现DFS 

邻接矩阵:

         邻接表:

二. 广度优先遍历(BFS)

邻接矩阵

邻接表


一.深度优先遍历(DFS)

1.DFS定义

假设给定图的所有状态都是未曾访问过.在G中任选一个点V作为初始点。则深度优先遍历的定义如下:

    首先访问出发点V,并将其标记为已访问过。然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的处发点继续进行深度优先遍历,直至图中所有和源点v路径相通的顶点均被访问。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。

图的深度优先遍历类似于图的前序遍历。采用搜索方法的特点是尽可能对纵深方向进行搜索。这种搜索方法被称为深度优先搜索

遍历过程:

(1)从图中的某个顶点开始访问;

(2)若顶点存在未被访问的邻接顶点,则继续访问它的其中一个邻接顶点

(3)重复步骤(2)直至某个顶点不存在未被访问的邻接顶点;

(4)从步骤(3)的某个顶点开始回溯访问,若回溯访问的邻接顶点存在未被访问的邻接顶点,则再执行步骤(2)(3)(4);

(5)重复步骤(2)(3)(4)直至所有顶点均被遍历,visted[n] 的值都非0

  这种一条路走到底,走不通再返回的特征正是“深度”一词的体现,“回溯”体现在标记数组visited[]中。

2.递归实现DFS

邻接矩阵:

int visited[MAX]
void DFSTrave(Graph G)
{
    for(int i=0;i

邻接表:

int visited[MAX];
void DFSTraverse(ALGraph G)
{
    for(int i=0;iadjvex])
            {
       	        DFS(G,p->adjvex);
	    }	
            p=p->nextarc;
	}	
}

3.非递归实现DFS 

借助栈实现
思路:

1.初始化栈 

2.输出起始的顶点,起始顶点改为“已访问”的标志,将起始顶点进栈

3.重复一下的操作直至栈为空:

        取栈顶元素顶点,存在着被访问的邻结点W 

        输出顶点W,将顶点W改为“已访问”,将W进栈

        否则,当前顶点退栈

 

邻接矩阵:

void dfs(MGraph G,int v)
{
   cout< s;//创建一个栈
   s.push(v);//入栈
   while(!s.empty())
   {
       int i,data;
       data=s.top();//取top的顶点
       for(i=0;i

邻接表:


void dfs(ALGraph G,int i)
{
    cout< ,因为G是结构体,P是结构体指针
    visited[i]=1;
    stack s;
    s.push(i);
    while(!s.empty())
    {
        ArcNode *p;
        p=G.vexs[s.top()].firstarc;
        while(p)
        {
            if(!visited[p->adjvex])
            {
                visited[p->adjvex]=1;
                cout<adjvex].data;
                s.push(p->adjvex);
                p=G.vexs[p->adjvex].firstarc;
            }
            else
                 p=p->nextarc;
         }
        if(!p)
        {
            s.pop();
        }
     }
}

 

二. 广度优先遍历(BFS)

广度优先搜索遍历类似于树的层次遍历。广度优先是一层一层地遍历,而不会从某个顶点开始一直往下遍历,直到不符合遍历的条件。以横向遍历为先,即访问顶点v1后,顺序访问v1的邻接顶点v2,v3,然后先顺序访问v2的邻接顶点,再顺序访问v3的邻接顶点,如此类推。

深度优先利用栈结构实现递归,广度优先则需要队列来实现每一层的顺序执行:

(1)v1入队,访问顶点v1,并在visited[]将顶点v1对应的元素值=1;

(2)检查v1的邻接顶点,v2和v3顺序入队

(3)v1出队

(4)访问顶点v2,检查v2的邻接顶点并使它们顺序入队

(5)v2出队,访问顶点v3;

(6)访问顶点v3,检查v3的邻接顶点并使它们顺序入队

(7)之后的入队、出队过程如此类推。

*利用队列“先来先服务”的性质,在编写代码时可以将思路转化为先求队列,再遍历。


邻接矩阵

void BFS(MGraph G)
{
	queueq;//队
	for(int i=0;i

邻接表

void BFS(ALGraph G)
{
    queueq;//队
    for(int i=0;iadjvex])
                    {//节点未被访问
                        visited[p->adjvex]=1;
                        cout<adjvex].data;
                        q.push(p->adjvex);//入队
                    }
                    p=p->nextarc;
                }
            }
        }
    }
}

 

你可能感兴趣的:(数据结构)