欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

广度(宽度)优先搜索:队列

程序员文章站 2022-03-14 08:52:30
...

上一章详细的写出了深度优先遍历的四种情况的程序:
http://blog.csdn.net/zscfa/article/details/75947816

这一次来详细说说广度优先遍历:
广度优先搜索类似于二叉树的层序遍历,它的基本思想就是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问过的邻接顶点w1,w2,…,wi,然后再依次访问w1,w2,…,wi的所有未被访问过的邻接顶点;再从这些访问过的顶点出发,再访问它们所有未被访问过的邻接顶点……依次类推,直到图中所有顶点都被访问过为止。
广度(宽度)优先搜索:队列
二、BFS算法的实现

与树相比,图的不同之处在于它存在回路/环,因此在遍历时一个顶点可能被访问多次。为了防止这种情况出现,我们使用一个访问标记数组visited[]来标记顶点是否已经被访问过。
在广度优先搜索一个图之前,我们首先要构造一个图,图的存储方式主要有两种:邻接矩阵、邻接表。

与上次一样,我们来分类说明

(一)、队列的方式实现
1、邻接矩阵

#include<iostream>
#include<stdlib.h>
#include<queue>

#define MAX 100

using namespace std;

int visited[MAX];//用来记录顶点是否被标志

typedef struct
{
    char ves[MAX];//图的顶点信息
    int vester;//顶点的数目
    int edge;//边的数目
    int e[MAX][MAX];//图的边的信息

}MGraph;

void creatMGraph(MGraph *G)
{
    cout<<"please input the ves and edge:"<<endl;
    cin>>G->vester>>G->edge;

    int i;
    int j;
    int start;
    int end;
//初始化
    for(i = 0; i < G->vester; i++)
    {
        for(j = 0; j < G->vester; j++)
    {
        G->e[i][j] = 0;
    }
        visited[i] = 0;
    }

    cout<<"please input the edge,(vi,vj)"<<endl;
    for(i = 0; i < G->edge; i++)
    {
        cin>>start>>end;
    G->e[start][end] = 1;//构建无向图
    G->e[start][end] = 1;
    }
}
/*主要思想:被访问过的点压入队列,*/

void BFS(MGraph* G,int i)
{
    int k;
    int j;

    queue<int> q;

    visited[i] = 1;//标志顶点i已经被访问了
    cout<<i;

    q.push(i);

    while(!q.empty())
    {
        k = q.front();
    q.pop();

    for(j = 1; j < G->vester; j++)
    {
        if(G->e[k][j] != 0 && visited[j] != 1)
        {
    cout<<"k = "<<k<<endl;
            cout<<j<<endl;;
        visited[j] = 1;
        q.push(j);
        }
    }
    }
}

int main()
{
//    MGraph G = (MGraph*)malloc(MGraph);
    MGraph G;
    creatMGraph(&G);

    BFS(&G,0);

    return 0;
}

结果:
广度(宽度)优先搜索:队列

2、邻接表


#include<iostream>
#include<stdlib.h>
#include<queue>

#define MAX 100

using namespace std;

int visited[MAX] = {0};

struct Node// 边表结点
{
    int adjves;//存储顶点的下标
    struct Node* next;//连接下一个邻点
};

typedef struct Node EdgeNode;

typedef struct VertexNode//顶点表结点
{
    int ves;//顶点的值
    EdgeNode* firstedge;//相连的顶点的值
}VertexNode,AdjList[MAX];

typedef struct
{
    AdjList adjlist;//邻接表
    int ves;//顶点
    int edge;//边
}MGraph;

void createMGraph(MGraph *G)
{
    int i;
    int start;
    int end;

    EdgeNode *e;

    cout<<"please input the ves and edge:"<<endl;
    cin>>G->ves>>G->edge;
//初始化
    cout<<"please input the ves:"<<endl;

    for(i = 0; i < G->ves; i++)//输入顶点
    {
        cin>>G->adjlist[i].ves;
    G->adjlist[i].firstedge = NULL;
    }
//创建邻接矩阵

    cout<<"please input the edges:"<<endl;;
    for(i = 0; i < G->edge; i++)
    {
        cin>>start>>end;

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
    e->adjves = end;
    e->next = G->adjlist[start].firstedge;
    G->adjlist[start].firstedge = e;//类似于链表的前插

        e =(EdgeNode*)malloc(sizeof(EdgeNode));//分配空间
    e->adjves = start;
    e->next = G->adjlist[end].firstedge;
    G->adjlist[end].firstedge = e;//类似于链表的前插
    }
}
void bfs(MGraph *G)
{
    int i;
    int k;

    EdgeNode* p;

    queue<int> q;

    for(i = 0; i < G->ves; i++)
    {
        visited[i] = 0;
    }
    for(i = 0; i < G->ves; i++)
    {
        if(visited[i] == 0)
    {
        visited[i] = 1;
        cout<<G->adjlist[i].ves;
        q.push(i);

        while(!q.empty())
        {
        k = q.front();
        q.pop();

        p = G->adjlist[k].firstedge;

        while(p)
        {
            if(visited[i] == 0)
            {
                visited[i] = 1;

                cout<<G->adjlist[p->adjves].ves;
            q.push(p->adjves);
            }
            p = p->next;
        }

        }
    }
    }
}
int main()
{
    MGraph G;
    createMGraph(&G);

    bfs(&G);
    return 0;
}

结果:
广度(宽度)优先搜索:队列