图的遍历非递归实现的思路



使用到的数据结构说明:

邻接表的形式说明

  typedef struct node{//边表结点

  int adjvex; //邻接点域

  struct node *next; //链域

  //若要表示边上的权,则应增加一个数据域

  }EdgeNode;

  typedef struct vnode{ //顶点表结点

  VertexType vertex; //顶点域

  EdgeNode *firstedge;//边表头指针

  }VertexNode;

  typedef VertexNode AdjList[MaxVertexNum];//AdjList是邻接表类型

  typedef struct{

  AdjList adjlist;//邻接表

  int n,e; 图中当前顶点数和边数

  }ALGraph;

一.广度优先遍历

   图的广度优先遍历是:对于每个结点而言先遍历其的兄弟结点,然后遍历其子节点。使用队列完成

   假设图的数据结构为邻接表。

   程序流程:

1.创建并初始队列

2.假如从V1结点开始遍历图,则输出V1,并将v1入队列

3.v1从队列中删除(以下3-5为循环体内的执行步骤)

4.循环遍历v1的所有邻接节点,对于v1的邻接节点,所示已经访问过,则跳过,否则,访问,并入队列。

5.第4步循环结束,则令指针指向下一个结点

6.当指针不为空时,循环3-5步。

代码:

void BFS(ALGraph* G,int k)//表示从Vk结点开始遍历

{

  Queue Q;

  EdgeNode *p;

  InitQueue(&Q);

  //访问源点Vk

  printf(G->adjlist[k].vertex);

  visited[k = true];//将k结点对应的标志设置为已遍历

  EnQueue(k);//k结点入队列

  while(!QueueEmpty(Q))

  {

    i = DeQueue(&Q);//上一个元素出队列

    p = G->adlist[i].fistage;

    while(p != NULL)

    {

       if(!visited[p->vertex])

      {

         printf(p->vertex);

         visited[p->vertex] = true;

         EnQueue(p->vertex);

       }

       p = p->next;

    }

  }

}

二.图的深度优先遍历

图的数据结构仍然使用邻接表

用栈实现深度优先遍历伪代码:

1.初始化栈

2.若第一个元素不为空,输出他,并压入栈

3.while(栈不为空)

{

  1.取出栈顶的元素,但是不要将其出栈

  2.遍历该元素的相邻结点是否有未被标记访问。若有,则访问,并标记为已访问,然后压入栈。

若都已经访问过,则将栈顶元素出栈

}

代码:

void DFS(ALGraph* G,int k)

{

  Stack s;

  InitStack(s);

  EdgeNode* p;

  int i;

  if(!visited[G->adlist[k].vertex] && G!=NULL)

  {

     printf(G->adlist[k].vertex);

     push(k);

  }

  while(!StackEmpty(s))//栈不为空说明还有节点未被访问

  {

     i = getTop(s);

    p = G->adlist[i]->fistage;

     while(p!=NULL)//遍历p节点的子节点,若是查到有未被访问的则结束循环

     {

        if(!visited[p->vertex])

        {

            visited[p->vertex] = true;

            printf(p->vertex);

            push(p->vertex);

            break;

         }

     }

     if(p == NULL)//这说明p节点所有子节点已经全部访问过,故需要弹出栈顶元素,那么下次循环时,p就指向前一个节点

     {

           pop(s);

     }

  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值