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

来源:互联网 发布:免费不充值约爱软件 编辑:程序博客网 时间:2024/06/07 05:21


使用到的数据结构说明:

邻接表的形式说明

  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