话不多说,直接上题目。
【问题描述】
很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示连通的无向图上,遍历全部结点的操作。
【基本要求】
以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。
【测试数据】
这里我将可视化数据提取特征,变为可利用数据,供大家使用:
25个地点:
北京
天津
沈阳
长春
哈尔滨
大连
徐州
上海
南昌
福州
株洲
广州
深圳
武汉
郑州
西安
成都
昆明
贵阳
柳州
南宁
呼和浩特
兰州
西宁
乌鲁木齐
30条边:
0 1
0 14
0 21
1 2
1 6
2 3
2 5
3 4
6 7
6 14
7 8
8 9
8 10
10 11
10 13
10 18
10 19
11 12
13 14
14 15
15 16
15 22
16 17
16 18
17 18
18 19
19 20
21 22
22 23
22 24
起点为北京
First step:构造多重邻接表
没有严格按照课本上的定义,若不然再创建一个图结构体即可。
struct edge{
int ru_node;
edge *ru_edge;
int chu_node;
edge *chu_edge;
};
struct node{
char location[100];
edge *chu_node;
};
那么如何构造多重邻接表,先上代码,稍后分析
node site[1000];
int n;
cout<<"Please input the number of locations"<<endl;
cin>>n;
cout<<"Please input the locations"<<endl;
for(int i = 0 ; i < n ; i ++){
cin>>site[i].location;
site[i].chu_node=NULL;
}
int m;
cout<<"Please input the number of edges"<<endl;
cin>>m;
edge *s;
for(int i = 0 ; i < m ; i ++){
s=(edge *)malloc(sizeof(edge));
cin>>s->ru_node;
cin>>s->chu_node;
s->ru_edge=site[s->ru_node].chu_node;
s->chu_edge=site[s->chu_node].chu_node;
site[s->ru_node].chu_node=s;
site[s->chu_node].chu_node=s;
}
如上,那么如何构建,大致的构造过程大家应该都了解,我只想说下一个比较容易出错的地方,那就是新构造的边结点不是像单链表那样插到最后,而是插入到数组那个指针和第一个边之间。这个道理在邻接表中仍然成立,我再具体讲下那几行代码。
s->ru_edge=site[s->ru_node].chu_node;
注意这是指针赋值运算,即令两个指针指向同一个地址。
site[s->ru_node].chu_node=s;
自己在脑海中想想,在下一轮,产生了新的结点,由上一行的指针赋值运算归规律我们得知,此时新结点与数组中的指针共同指向了旧结点,再将数组中的指针改变指向,指向新结点,这个插入操作也就完成了,本人从邻接表的创建方法中借鉴过来,感觉这种方法很巧妙。
创建完具体的多重邻接表,下一步则是具体的深度优先搜索与广度优先搜索,使用的算法也就是我们常说的DFS算法与BFS算法了。
这里我使用的DFS算法是非递归的,觉得在外面写个函数较为繁琐,且递归函数具有其本身的缺点。
stack<int> location;
queue<int> vex1;
queue<int> vex2;
int vist[1000]={
0};
int count = 0 ;
cout<<"Please the origin"<<endl;
char a[20];
int origin;
cin>>a;
for(int i = 0 ; i < n ; i ++){
if(!strcmp(a,site[i].location)){
origin=i;
break;
}}
cout<<"The DFS travesal order is:"<<endl