图的广度优先遍历

基本思想
1、从图中某个顶点V0出发,并访问此顶点;
2、从V0出发,访问V0的各个未曾访问的邻接点W1,W2,…,Wk;然后,依次从W1,W2,…,Wk出发访问各自未被访问的邻接点;
3、重复步骤2,直到全部顶点都被访问为止。

类似于树的按层次遍历,也就是一层一层地遍历,图的广度优先遍历从图中的某个结点出发,访问它的邻结点再访问邻结点的邻结点,由近及远。

这里写图片描述

如上图:从A出发,依次访问A结点的邻接点B、C、D,再访问B的邻接E,再访问C的邻接点F,左边访问完后,访问右边D的邻结点G和H,再访问G的邻接点 I, 至此所有的结点都已访问,遍历过程结束。遍历顺序为:

A->B->C->D->E->F->G->H->I

这里需要借助一个辅助的队列和来暂时存放已经访问过的结点,和
访问标志数组。

C语言代码:

#include<stdio.h>
#include<stdlib.h>
#define MaxVex 20
typedef char Vertex;
typedef struct SStation              //接邻结点结构 
{
    int adjvex;                      //该边所指的顶点的位置
    int weight;                      //权值,路的距离 
    struct SStation *next;
}StationNode;

typedef struct 
{
    Vertex data;                       //顶点信息,如站点名称 
    StationNode *firstedge;            //指向第一条依附该顶点的弧的指针 
}VNode,Vex[MaxVex]; 

typedef struct{    
    Vex vertices;                     //邻接表
    bool visited[MaxVex];    //访问标志数组
    int n,e;                          //顶点数和边数 
}ALGraph;

//队列定义及相关操作(广度遍历会用到此循环队列)
typedef struct LoopQueue
{
    int data[MaxVex];
    int front,rear;
}Queue;

void InitQueue(Queue &Q)
{//初始化队列 
    Q.front = Q.rear = 0;
}
bool QueueFull(Queue &Q)
{//判断队满 
    if((Q.rear+1)%MaxVex == Q.front)
     return true;
    else 
     return false;
}

bool QueueEmpty(Queue &Q)
{//判断队空
  if(Q.front == Q.rear)
   return true;
  else 
   return false; 
}

void EnQueue(Queue &Q,int e) 
{//入队 
    if(!QueueFull(Q)) 
     {
        Q.data[Q.rear] = e;
        Q.rear = (Q.rear+1)%MaxVex;
     }
}

void DeQueue(Queue &Q,int &e)
{//出队列
    if(!QueueEmpty(Q))
    {
        e = Q.data[Q.front];
        Q.front = (Q.front+1)%MaxVex; 
    } 
}

void InitVexs(ALGraph &G)
{//建立顶点表 
     int i;
     printf("建立顶点表,请输入顶点个数: ");
     scanf("%d",&(G.n));
     for(i=0; i<G.n; i++)
     {
       printf("\n请输入第%d个顶点:",i+1);
       fflush(stdin);
       G.vertices[i].data = getchar();
       G.vertices[i].firstedge = NULL;
     }
}

void InitEdge(ALGraph &G)
{//建立边表 
    StationNode *s;
    int i,j,k,w;
    fflush(stdin);
    printf("建立边表,请输入边数: ");
    scanf("%d",&(G.e));
    for(k=0;k<G.e;k++)
    { 
      fflush(stdin);  
      printf("\n读入(vi-vj)的顶点对序号和权值,中间用','隔开:");         //新建邻接结点 
      scanf("%d,%d",&i,&j,&w);  
      s = (StationNode*)malloc(sizeof(StationNode));
      s->adjvex = j;
      s->weight = w;
      s->next = NULL;

      if(!G.vertices[i].firstedge)
        G.vertices[i].firstedge = s;               //接在表头  
      else
      {
        StationNode *p = G.vertices[i].firstedge;
        while(p->next)
            p = p->next;
        p->next = s; 
      }  
    }
}

void Visit(ALGraph &G,int i)
{
     printf("%c->",G.vertices[i].data);
     G.visited[i] = true;
}

void BFSTraverse(ALGraph &G) 
{//广度优先非递归遍历图,借助队列和访问标志数组 
   int j,u;
   Queue Q;
   InitQueue(Q);
   for(j=0; j<G.n; j++)
    G.visited[j] = false;                      //初始时默认所有顶点都未访问过
   for(j=0; j<G.n; j++)
     if(!G.visited[j])                        //序号为j未的顶点未访问过
     { 
          Visit(G,j);
          EnQueue(Q,j);                       //结点j入队列
          while(!QueueEmpty(Q))
          {
             DeQueue(Q,u);                   //队头元素出队并置为u 
             for(StationNode *p = G.vertices[u].firstedge; p != NULL; p=p->next)
               if(!G.visited[p->adjvex])
               {
                Visit(G,p->adjvex);
                EnQueue(Q,p->adjvex);
               }//if
          }//while 
     } //if
}//BFSTraverse

int main()
{
  ALGraph G;
  InitVexs(G);
  InitEdge(G);
  printf("广度优先遍历结果: ");
  BFSTraverse(G);
  system("PAUSE");
  return 0;
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值