zoukankan      html  css  js  c++  java
  • 图的存储及遍历 深度遍历和广度遍历 C++代码实现

    /*图的存储及遍历*/  
    #include<iostream>  
    using namespace std;  
    //-----------------------------------  
    //邻接矩阵的存储及深度和广度遍历  
    //-----------------------------------  
       
    /*邻接矩阵的类型定义*/  
    #define MAX 10000000  
    #define MAX_VERTEX_NUM 20  
    typedef enum{ DG,DN,UDG,UDN }GraphKind;//有向图,有向网,无向图,无向网  
    typedef struct  
    {  
           char vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息  
           int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组充当矩阵,来存储顶点边的信息  
           int vexnum,edgenum;//顶点树和边数  
           GraphKind kind;//图的种类  
    }MGraph;  
       
    /*构造无向图的邻接矩阵*/  
    void CreateUDG_AM(MGraph &G,int n,int e)  
    {  
           G.vexnum=n;  
           G.edgenum=e;  
            
           int i,j,k;  
           for(i=0;i<n;i++)  
                  cin>>G.vexs[i];//输入顶点信息  
       
           for(i=0;i<n;i++)  
                  for(j=0;j<n;j++)  
                         G.edges[i][j]=0;//将矩阵初始化为0  
       
           for(k=0;k<e;k++)  
           {  
                  cin>>i>>j;//这里只用输入对称的边就行,也就是输入下矩阵或是上矩阵  
                  G.edges[i][j]=G.edges[j][i]=1;//输入边的信息  
           }  
    }  
       
    /****************************无向图的深度优先遍历************************/  
    int visited[MAX_VERTEX_NUM];  
       
    void DF_AM(MGraph &G,int i)  
    {  
           int j;  
           cout<<G.vexs[i]<<" ";  
           visited[i]=1;  
           for(j=0;j<G.vexnum;j++)  
           {  
                  if((G.edges[i][j])==1&&(visited[j])==0)  
                         DF_AM(G,j);  
           }  
    }  
       
    void DF_Traverse_AM(MGraph &G)  
    {  
           int i;  
           for(i=0;i<G.vexnum;i++)  
           {  
                  visited[i]=0;  
           }  
           for(i=0;i<G.vexnum;i++)  
           {  
                  if(!visited[i])  
                         DF_AM(G,i);  
           }  
    }  
       
    /*********************无向图的广度优先遍历*****************************/  
       
    //循环队列的类型定义  
    const int Queue_Size=100;  
       
    typedef struct circlQueue  
    {  
           int *elem;  
           int rear;  
           int front;  
           int queueSize;  
    }circlQueue;  
       
    //初始化  
    void initQueue_C(circlQueue &Q)  
    {  
           Q.elem=new int[Queue_Size];  
           Q.front=Q.rear=0;//首尾指针相等说明队列为空。  
           Q.queueSize=Queue_Size;  
    }  
       
    //入队列  
    void enterQueue_C(circlQueue &Q,int x)  
    {  
           if(((Q.rear+1)%Q.queueSize)==Q.front)//判断栈满的情况  
                  cout<<"Queue OverFlow!";  
           Q.elem[Q.rear]=x;  
           Q.rear=(Q.rear+1)%Queue_Size;//尾指针应以此种方式加1,才会实现循环队列。  
    }  
       
    //出队列  
    char outputQueue_C(circlQueue &Q)  
    {  
           int e;  
           if(Q.rear==Q.front)  
                  cout<<"Queue Empty";  
           e=Q.elem[Q.front];  
           Q.front=(Q.front+1)%Q.queueSize;;//头指针应以此种方式加1,才会实现循环队列。  
           return e;  
    }  
    //广度遍历  
    void BF_Traverse_AM(MGraph &G)  
    {  
           int i,j,v;  
           for(i=0;i<G.vexnum;i++)  
                  visited[i]=0;  
           circlQueue Q;  
           initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问  
           for(i=0;i<G.vexnum;i++)  
           {  
                  if(!visited[i])  
                  {  
                         cout<<G.vexs[i]<<" ";  
                         visited[i]=1;  
                         enterQueue_C(Q,i);  
                         while(Q.front!=Q.rear)  
                         {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环  
                                v=outputQueue_C(Q);  
                                for(j=0;j<G.vexnum;j++)  
                                {//这个循环是将顶点的全部邻接点依次访问并且入队列  
                                       if(G.edges[v][j]&&(!visited[j]))  
                                       {  
                                              cout<<G.vexs[j]<<" ";  
                                              visited[j]=1;  
                                              enterQueue_C(Q,j);  
                                       }  
                                }  
                         }  
                  }  
           }  
    }  
       
    //-----------------------------------------------  
    //邻接表的存储及深度和广度遍历  
    //-----------------------------------------------  
    typedef struct EdgeNode  
    {//边表结点的定义  
           int adjvex;//存放邻接点在顶点表中的位置  
           struct EdgeNode * nextedge;//指向下一个边表结点  
           int weight;  
    }EdgeNode;  
       
    typedef struct VexNode  
    {//顶点表结点的定义  
           char vex;//存放顶点信息  
           EdgeNode * firstedge;//指向第一个边表结点  
    }VexNode;  
       
    typedef struct  
    {//顶点表的定义    
           VexNode vexs[MAX_VERTEX_NUM];  
           int vexnum,edgenum;  
           GraphKind kind;  
    }LGraph;  
       
    /*构造有向图的邻接表*/  
    void CreateDG_AL(LGraph &G,int n,int e)  
    {  
           int i,j,k;  
           G.vexnum=n;  
           G.edgenum=e;  
           G.kind=DG;  
           for(i=0;i<n;i++)  
           {  
                  cin>>G.vexs[i].vex;  
                  G.vexs[i].firstedge=NULL;//初始化为空  
           }  
           for(k=0;k<e;k++)  
           {  
                  EdgeNode *p;  
                  cin>>i>>j;  
                  p=new EdgeNode;  
                  p->adjvex=j;  
                  p->nextedge=G.vexs[i].firstedge;  
                  G.vexs[i].firstedge=p;//采用头插法  
           }  
    }  
       
    /*********************有向图的深度优先遍历**************************/  
    void DF_AL(LGraph &G,int v)  
    {  
           int j;  
           EdgeNode *p;  
           cout<<G.vexs[v].vex<<" ";  
           visited[v]=1;  
           for(p=G.vexs[v].firstedge;p;p=p->nextedge)  
           {  
                  j=p->adjvex;  
                  if(!visited[j])  
                         DF_AL(G,j);  
           }  
    }  
       
    void DF_Traverse_AL(LGraph &G)  
    {  
           int i;  
           for(i=0;i<G.vexnum;i++)  
           {  
                  visited[i]=0;  
           }  
           for(i=0;i<G.vexnum;i++)  
           {  
                  if(!visited[i])  
                         DF_AL(G,i);  
           }  
    }  /* 何问起 hovertree.com */
    /*********************有向图的广度优先遍历**************************/  
    void BF_Traverse_AL(LGraph &G)  
    {  
           int i,j,v;  
           EdgeNode *p;  
           for(i=0;i<G.vexnum;i++)  
                  visited[i]=0;  
           circlQueue Q;  
           initQueue_C(Q);//队列实现了“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问  
           for(i=0;i<G.vexnum;i++)  
           {  
                  if(!visited[i])  
                  {  
                         cout<<G.vexs[i].vex<<" ";  
                         visited[i]=1;  
                         enterQueue_C(Q,i);  
                         while(Q.front!=Q.rear)  
                         {//这个循环是将队列里面的顶点取出来,然后进行下面的for循环  
                                v=outputQueue_C(Q);  
                                for(p=G.vexs[v].firstedge;p;p=p->nextedge)  
                                {//这个循环是将顶点的全部邻接点依次访问并且入队列  
                                       j=p->adjvex;  
                                       if(!visited[j])  
                                       {  
                                              cout<<G.vexs[j].vex<<" ";  
                                              visited[j]=1;  
                                              enterQueue_C(Q,j);  
                                       }  
                                }  
                         }  
                  }  
           }  
    }  
    void main()  
    {  
           /*MGraph G; 
           CreateUDG_AM(G,6,6); 
           DF_Traverse_AM(G); 
           cout<<endl; 
           BF_Traverse_AM(G);*/  
       
           LGraph G;  
           CreateDG_AL(G,5,7);  
           DF_Traverse_AL(G);  
           cout<<endl;  
           BF_Traverse_AL(G);  
    }  

    写这个程序给我的感觉就是乱,思路不是很清晰,遍历的逻辑关系还掌握的不是很熟,只是大概知道是这么回事,但是让自己去写的话,可能就写不出来了!还是要加大对遍历的熟悉程度才行啊!

    PS:另外推荐一个让大家真正练手的网站:猪八戒威客网,在这里可以按自己的能力去接一些程序设计的任务。我觉得这是一种很不错的学习方法,当你接了别人的任务,无形中就给了自己压力和动力,然后就会主动的去查询资料,分析问题,可能会历经艰辛才能解决问题,但这中间的过程是很珍贵的,你会通过自己的努力学到很多课本上没有学到的东西,也能过一回需求分析的瘾,真实的体会到和客户进行交流的诸多“纠结”,最后,如果你的努力得到客户的认可,可以获得一笔小小的佣金,当做对自己的奖励,更重要的是,通过做任务,你能体会到自己存在的价值感和对自己能力的肯定!

    推荐:http://www.cnblogs.com/roucheng/p/cpphong.html

  • 相关阅读:
    制作基于OK6410的文件系统(2.修改busybox文件系统,使之能启动)
    [转]SlickEdit 2012
    移植TPLINK TLWN721N 驱动到micro2440(by liukun321咕唧咕唧)
    擦,买到了伪劣的SD卡
    Slickedit中文显示与输入
    OMAP3530mini调试笔记(2)
    最近在做linux的移植工作
    嵌入式linux启动时运行的inittab文件(zz)
    OMAP3530mini调试笔记(1)
    Ubuntu中音量调节无效的解决方法
  • 原文地址:https://www.cnblogs.com/roucheng/p/cppbianli.html
Copyright © 2011-2022 走看看