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 }

 

posted @ 2012-12-06 22:39  maowang  阅读(250)  评论(0编辑  收藏  举报