[C++] 图的遍历算法 →→→→→进入此内容的聊天室

来自 , 2019-06-13, 写在 C++, 查看 101 次.
URL http://www.code666.cn/view/fface838
  1. #include <dos.h>
  2. #include <conio.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #define MAX_VERTEX_NUM 20 //图的最大顶点数
  7. #define MAXQSIZE 30       //队列的最大容量
  8. enum BOOL {False,True};
  9. typedef struct ArcNode
  10. {
  11.         int adjvex;              //该弧所指向的顶点的位置
  12.         struct ArcNode *nextarc; //指向下一条弧的指针
  13. } ArcNode;      //弧结点
  14. typedef struct
  15. {
  16.         ArcNode* AdjList[MAX_VERTEX_NUM]; //指向第一条依附该顶点的弧的指针
  17.         int vexnum,arcnum;                //图的当前顶点和弧数
  18.         int GraphKind;    //图的种类,0---无向图,1---有向图
  19. } Graph;
  20. typedef struct        //队列结构
  21. {
  22.         int  elem[MAXQSIZE]; //数据域
  23.         int front;           //队头指针
  24.         int rear;            //队尾指针
  25. } SqQueue;
  26. BOOL visited[MAX_VERTEX_NUM]; //全局变量——访问标志数组
  27. void CreateGraph ( Graph & ); //生成图的邻接表
  28. void DFSTraverse ( Graph );   //深度优先搜索遍历图
  29. void DFS ( Graph,int );
  30. void BFSTraverse ( Graph );   //广度优先搜索遍历图
  31. void Initial ( SqQueue & );   //初始化一个队列
  32. BOOL QueueEmpty ( SqQueue );  //判断队列是否空
  33. BOOL EnQueue ( SqQueue &,int );   //将一个元素入队列
  34. BOOL DeQueue ( SqQueue &,int & ); //将一个元素出队列
  35. int  FirstAdjVex ( Graph,int );   //求图中某一顶点的第一个邻接顶点
  36. int  NextAdjVex ( Graph,int,int ); //求某一顶点的下一个邻接顶点
  37. void main()
  38. {
  39.         Graph G;  //采用邻接表结构的图
  40.         char j='y';
  41.         textbackground ( 3 );  //设定屏幕颜色
  42.         textcolor ( 15 );
  43.         clrscr();
  44. //------------------程序解说----------------------------
  45.         printf ( "本程序将演示生成一个图,并对它进行遍历.\n" );
  46.         printf ( "首先输入要生成的图的种类.\n" );
  47.         printf ( "0---无向图, 1--有向图\n" );
  48.         printf ( "之后输入图的顶点数和弧数。\n格式:顶点数,弧数;例如:4,3\n" );
  49.         printf ( "接着输入各边(弧尾,弧头).\n例如:\n1,2\n1,3\n2,4\n" );
  50.         printf ( "程序会生成一个图,并对它进行深度和广度遍历.\n" );
  51.         printf ( "深度遍历:1->2->4->3\n广度遍历:1->2->3->4\n" );
  52. //------------------------------------------------------
  53.         while ( j!='N'&&j!='n' )
  54.         {
  55.                 printf ( "请输入要生成的图的种类(0/1):" );
  56.                 scanf ( "%d",&G.GraphKind ); //输入图的种类
  57.                 printf ( "请输入顶点数和弧数:" );
  58.                 scanf ( "%d,%d",&G.vexnum,&G.arcnum ); //输入图的顶点数和弧数
  59.                 CreateGraph ( G );    //生成邻接表结构的图
  60.                 DFSTraverse ( G );    //深度优先搜索遍历图
  61.                 BFSTraverse ( G );    //广度优先搜索遍历图
  62.                 printf ( "图遍历完毕,继续进行吗?(Y/N)" );
  63.                 scanf ( " %c",&j );
  64.         }
  65. }
  66.  
  67. void CreateGraph ( Graph &G )
  68. {//构造邻接表结构的图G
  69.         int i;
  70.         int start,end;
  71.         ArcNode *s;
  72.         for ( i=1; i<=G.vexnum; i++ ) G.AdjList[i]=NULL; //初始化指针数组
  73.         for ( i=1; i<=G.arcnum; i++ )
  74.         {
  75.                 scanf ( "%d,%d",&start,&end ); //输入弧的起点和终点
  76.                 s= ( ArcNode * ) malloc ( sizeof ( ArcNode ) ); //生成一个弧结点
  77.                 s->nextarc=G.AdjList[start]; //插入到邻接表中
  78.                 s->adjvex=end;
  79.                 G.AdjList[start]=s;
  80.                 if ( G.GraphKind==0 )  //若是无向图,再插入到终点的弧链中
  81.                 {
  82.                         s= ( ArcNode * ) malloc ( sizeof ( ArcNode ) );
  83.                         s->nextarc=G.AdjList[end];
  84.                         s->adjvex=start;
  85.                         G.AdjList[end]=s;
  86.                 }
  87.         }
  88. }
  89. void DFSTraverse ( Graph G )
  90. {//深度优先遍历图G
  91.         int i;
  92.         printf ( "DFSTraverse:" );
  93.         for ( i=1; i<=G.vexnum; i++ ) visited[i]=False; //访问标志数组初始化
  94.         for ( i=1; i<=G.vexnum; i++ )
  95.                 if ( !visited[i] ) DFS ( G,i ); //对尚未访问的顶点调用DFS
  96.         printf ( "\b\b  \n" );
  97. }
  98. void DFS ( Graph G,int i )
  99. {//从第i个顶点出发递归地深度遍历图G
  100.         int w;
  101.         visited[i]=True;  //访问第i个顶点
  102.         printf ( "%d->",i );
  103.         for ( w=FirstAdjVex ( G,i ); w; w=NextAdjVex ( G,i,w ) )
  104.                 if ( !visited[w] ) DFS ( G,w ); //对尚未访问的邻接顶点w调用DFS
  105. }
  106.  
  107. void BFSTraverse ( Graph G )
  108. {//按广度优先非递归的遍历图G,使用辅助队列Q和访问标志数组visited
  109.         int i,u,w;
  110.         SqQueue Q;
  111.         printf ( "BFSTreverse:" );
  112.         for ( i=1; i<=  G.vexnum; i++ )  visited[i]=False; //访问标志数组初始化
  113.         Initial ( Q );  //初始化队列
  114.         for ( i=1; i<=G.vexnum; i++ )
  115.                 if ( !visited[i] )
  116.                 {
  117.                         visited[i]=True;  //访问顶点i
  118.                         printf ( "%d->",i );
  119.                         EnQueue ( Q,i );  //将序号i入队列
  120.                         while ( !QueueEmpty ( Q ) ) //若队列不空,继续
  121.                         {
  122.                                 DeQueue ( Q,u );   //将队头元素出队列并置为u
  123.                                 for ( w=FirstAdjVex ( G,u ); w; w=NextAdjVex ( G,u,w ) )
  124.                                         if ( !visited[w] )  //对u的尚未访问的邻接顶点w进行访问并入队列
  125.                                         {
  126.                                                 visited[w]=True;
  127.                                                 printf ( "%d->",w );
  128.                                                 EnQueue ( Q,w );
  129.                                         }
  130.                         }
  131.                 }
  132.         printf ( "\b\b  \n" );
  133. }
  134.  
  135. int FirstAdjVex ( Graph G,int v )
  136. {//在图G中寻找第v个顶点的第一个邻接顶点
  137.         if ( !G.AdjList[v] ) return 0;
  138.         else return ( G.AdjList[v]->adjvex );
  139. }
  140. int NextAdjVex ( Graph G,int v,int u )
  141. {//在图G中寻找第v个顶点的相对于u的下一个邻接顶点
  142.         ArcNode *p;
  143.         p=G.AdjList[v];
  144.         while ( p->adjvex!=u ) p=p->nextarc; //在顶点v的弧链中找到顶点u
  145.         if ( p->nextarc==NULL ) return 0; //若已是最后一个顶点,返回0
  146.         else return ( p->nextarc->adjvex );  //返回下一个邻接顶点的序号
  147. }
  148.  
  149. void Initial ( SqQueue &Q )
  150. {//队列初始化
  151.         Q.front=Q.rear=0;
  152. }
  153. BOOL QueueEmpty ( SqQueue Q )
  154. {//判断队列是否已空,若空返回True,否则返回False
  155.         if ( Q.front==Q.rear ) return True;
  156.         else return False;
  157. }
  158.  
  159. BOOL EnQueue ( SqQueue &Q,int ch )
  160. {//入队列,成功返回True,失败返回False
  161.         if ( ( Q.rear+1 ) %MAXQSIZE==Q.front ) return False;
  162.         Q.elem[Q.rear]=ch;
  163.         Q.rear= ( Q.rear+1 ) %MAXQSIZE;
  164.         return True;
  165. }
  166.  
  167. BOOL DeQueue ( SqQueue &Q,int &ch )
  168. {//出队列,成功返回True,并用ch返回该元素值,失败返回False
  169.         if ( Q.front==Q.rear ) return False;
  170.         ch=Q.elem[Q.front];
  171.         Q.front= ( Q.front+1 ) %MAXQSIZE;
  172.         return True;                     //成功出队列,返回True
  173. }
  174.  

回复 "图的遍历算法"

这儿你可以回复上面这条便签

captcha