zoukankan      html  css  js  c++  java
  • alGraph.h

      1 #ifndef ALGRAPH_H
      2 #define ALGRAPH_H
      3 
      4 #include <stdio.h>
      5 #include <stdlib.h>
      6 #include <malloc.h>
      7 #include <queue>
      8 
      9 #define MAX_VERTEX_NUM 20
     10 
     11 typedef char InfoType;
     12 typedef int VertexType;
     13 
     14 typedef enum{ERROR,OK} Status;
     15 
     16 //---图的邻接表存储,本程序中为使用此存储方式
     17 typedef struct ArcNode//弧节点
     18 {
     19     int adjvex;
     20     InfoType *info;
     21     struct ArcNode *nextarc;
     22 }ArcNode;
     23 
     24 typedef struct VNode//顶点节点
     25 {
     26     VertexType data;//顶点信息
     27     ArcNode *firstAdj;//指向第一条依附该顶点的弧的指针
     28 }VNode,AdjList[MAX_VERTEX_NUM];
     29 
     30 typedef struct 
     31 {
     32     AdjList vertices;
     33     int vexnum,arcnum;
     34     int kind;
     35 }ALGraph;
     36 
     37 //---图的十字链表存储,本程序中使用的此存储方式
     38 typedef struct ArcBox
     39 {
     40     int tailvex,headvex;
     41     struct ArcBox *hlink,*tlink;
     42     InfoType *info;
     43 }ArcBox;
     44 
     45 typedef struct VexNode
     46 {
     47     VertexType data;
     48     ArcBox *firstin,*firstout;
     49 }VexNode;
     50 
     51 typedef struct 
     52 {
     53     VexNode xlist[MAX_VERTEX_NUM];
     54     int vexnum,arcnum;
     55 }OLGraph;
     56 
     57 Status (*VisitFun)(VexNode ar);//遍历树时使用的函数
     58 int visited[MAX_VERTEX_NUM];//访问数组,用来标志是否被访问过
     59 
     60 int Locate(OLGraph g,int x)//根据值获取数组下标
     61 {
     62     for(int i = 0;i < g.arcnum;i++)
     63     {
     64         if(x == g.xlist[i].data)
     65         {
     66             return i;
     67         }
     68     }
     69     return -1;
     70 }
     71 
     72 Status CreateOLGraph(OLGraph &g)//用户输入值,转化为位置存储,输出时再将位置转化为值输出给用户,即相当于在内部存取都是位置,从0开始,但在与用户交互时都是使用值而非位置
     73 {
     74     int incinfo;
     75     scanf("%d %d %d",&g.vexnum,&g.arcnum,&incinfo);//incinfo如果为0则边的info为空,incinfo为1则需要输入info
     76 
     77     printf("please input the value of vex :\n");
     78     for(int i = 0;i < g.vexnum;i++)//输入节点的值
     79     {
     80         scanf("%d",&g.xlist[i].data);
     81         g.xlist[i].firstin = NULL;
     82         g.xlist[i].firstout = NULL;
     83     }
     84 
     85     printf("please input the value of arc:\n");
     86     for(int i = 0;i < g.arcnum;i++)
     87     {
     88         int k,j;//k1和j1是节点的值,需要通过locate函数得到其在xlist中的位置(即数组下标)
     89         scanf("%d %d",&j,&k);
     90 
     91         j = Locate(g,j);
     92         if(j == -1)
     93         {
     94             printf("cannot locate the vertex!\n");
     95             return ERROR;
     96         }
     97 
     98         k = Locate(g,k);
     99         if(k == -1)
    100         {
    101             printf("cannot locate the vertex!\n");
    102             return ERROR;
    103         }
    104 
    105         ArcBox *ar = (ArcBox *)malloc(sizeof(ArcBox));
    106         //这里类似于链表的头插法建立链表,所以越是往后输入的边的端点越是在链表的表头,因此在后面遍历时,会感觉和输入的边的顺序相反,相反才说明正确
    107         ar->hlink = g.xlist[k].firstin;
    108         ar->tlink = g.xlist[j].firstout;
    109         ar->headvex = k;
    110         ar->tailvex = j;
    111         g.xlist[j].firstout = ar;
    112         g.xlist[k].firstin = ar;
    113 
    114         if(incinfo)
    115         {
    116             char aa;
    117             scanf("%c",&aa);
    118             ar->info = &aa;
    119         }
    120         else
    121         {
    122             ar->info = "";
    123         }
    124     }
    125     return OK;
    126 }
    127 
    128 Status PrintOLGraph(OLGraph g)
    129 {
    130     printf("the value of the vertex and arcvalue is :\n");//输出的值和内部存储的值不一定相同,内部存储全是存储位置,因此要转化为值输出
    131     for(int i = 0;i < g.vexnum;i++)
    132     {
    133         printf("%d\n",g.xlist[i].data);
    134         ArcBox *temp = g.xlist[i].firstout;
    135         while(temp)
    136         {
    137             printf("(%d %d) ",g.xlist[temp->tailvex].data,g.xlist[temp->headvex].data);
    138             temp = temp->tlink;
    139         }
    140         printf("\n");
    141     }
    142     return OK;
    143 }
    144 
    145 int FirstAdjVex(OLGraph g,int v)
    146 {
    147     if(g.xlist[v].firstout)
    148     {
    149         int nu = g.xlist[v].firstout->headvex;
    150         if(visited[nu] == 0)
    151         {
    152             return nu;
    153         }
    154     }
    155     else
    156     {
    157         return -1;
    158     }
    159 }
    160 
    161 int NextAdjVex(OLGraph g,int v,int w)
    162 {
    163     ArcBox *temp = g.xlist[v].firstout;
    164     while(temp->headvex != w)
    165     {
    166         temp = temp->tlink;
    167     }
    168 
    169     temp = temp->tlink;
    170     if(temp && visited[temp->headvex] == 0)
    171     {
    172         return temp->headvex;
    173     }
    174     else
    175     {
    176         return -1;
    177     }
    178 }
    179 
    180 Status visit(VexNode ar)
    181 {
    182     printf("%d\n",ar.data);
    183     return OK;
    184 }
    185 
    186 void Dfs(OLGraph g,int num)
    187 {
    188     if(!visited[num])
    189     {
    190         VisitFun(g.xlist[num]);
    191         visited[num] = 1;
    192     }
    193     for(int m = FirstAdjVex(g,num);m >= 0;m = NextAdjVex(g,num,m))
    194     {
    195         if(!visited[m])
    196         {
    197             Dfs(g,m);
    198         }
    199     }
    200 }
    201 
    202 void DFSTraverse(OLGraph g,Status (*visit)(VexNode ar))//深度遍历树
    203 {
    204     for(int i = 0;i < g.vexnum;i++)
    205     {
    206         visited[i] = 0;//初始化访问数组
    207     }
    208 
    209     VisitFun = visit;//初始化全局变量函数指针,使得Dfs函数中也可以调用访问函数
    210     for(int i = 0;i < g.vexnum;i++)
    211     {
    212         if(!visited[i])
    213         {
    214             Dfs(g,i);
    215         }
    216     }
    217 }
    218 
    219 void BFSTraverse(OLGraph g,Status (*visit)(VexNode ar))//广度优先遍历树
    220 {
    221     for(int i = 0;i < g.vexnum;i++)
    222     {
    223         visited[i] = 0;
    224     }
    225 
    226     std::queue<int> q;//辅助队列,用来存放xlist数组节点的下标而不是节点本身,存放下标方便些
    227 
    228     for(int i = 0;i < g.vexnum;i++)
    229     {    
    230         if(!visited[i])
    231         {    
    232             visit(g.xlist[i]);
    233             q.push(i);
    234             visited[i] = 1;
    235             int temp;
    236 
    237             while(!q.empty())
    238             {
    239                 temp = q.front();
    240                 q.pop();
    241                 for(int w = FirstAdjVex(g,temp);w >= 0;w = NextAdjVex(g,temp,w))
    242                 {
    243                     if(visited[w] == 0)
    244                     {
    245                         visited[w] = 1;
    246                         visit(g.xlist[w]);
    247                         q.push(w);
    248                     }
    249                 }
    250             }
    251         }
    252     }
    253 }
    254 
    255 #endif

    main.cpp

     1 #include "alGraph.h"
     2 
     3 int main()
     4 {
     5     OLGraph g;
     6 
     7     CreateOLGraph(g);
     8     PrintOLGraph(g);
     9 
    10     printf("DFSTraverse:\n");
    11     DFSTraverse(g,visit);
    12 
    13     printf("BFSTraverse:\n");
    14     BFSTraverse(g,visit);
    15 
    16     system("pause");
    17     return 0;
    18 }
  • 相关阅读:
    最大流问题的几种经典解法综述
    有上下界的网络流
    hiho一下
    poj 1018
    状压dp
    hdu 1043
    Poj1015
    7.14
    sgu 128
    (zhuan)
  • 原文地址:https://www.cnblogs.com/maowang1991/p/2806285.html
Copyright © 2011-2022 走看看