目录
实验题目
如下图G采用图的邻接表存储,采用深度优先遍历算法遍历图中结点,给定实参DFS(G,3),写出遍历顶点的结果(要求上机实现完整程序代码、核心代码有注释,有运行结果)。
实验思路
头结点
首先我们要理解邻接表是怎么存放图中结点的,图中的0到4分别对应邻接表中的v0到v4的4个表头,为此,我们需要定义表头这样一个struct。
struct headnode {
string data;
danweinode *firstarc;
//这个是头结点,这个指针指向头结点的下一个结点
};
单位结点
其次每个表头都会连接上单位结点,从图中来看,单位结点就是当前表头所连接到的结点,比如对于图中的2来说,它连接着1,3,4,因此在右侧v2表头连接着1,3,4这三个单位结点,由此,我们定义出struct单位结点。
struct danweinode {
int adjvex;
struct danweinode * nextarc;
//这个指针指向单位结点的后一个结点
};
//表示头结点后面的单位结点
额外信息
最后我们还需要一个struct用来存放所有的表头结点,还有边的数目,顶点数目等额外信息,因此,我将这个struct命名为extrainfo。
//定义用于存储额外信息的结构体
struct extrainfo {
headnode hnode[5];
//用于存储头结点
int vexnum;
int edgenum;
//顶点数目和边的数目
};
邻接表的DFS
结合图片模拟过程理解邻接表的DFS。
最后就是关键的DFS了,题目要求为从结点3开始遍历,所以先输出3,由邻接表,结点3后一个为结点0,因为0结点尚未走过,于是转化到v0头结点,输出0,v0头结点的后一个1,恰好1也没走过,于是转换到v1,输出1,v1头结点之后为0,已经走过,于是往后到2,尚未走过,于是转换到v2,输出2,v2之后为1,已经走过,于是往后到3,也走过,继续到4,没有走,于是转换到v4,输出4,再遍历v4后的结点发现都走过了,于是结束dfs。
dfs的结果就为:30124
具体代码为:
bool visited[5];
//走过就标记为1
void DFS(extrainfo g,int u) {
visited[u] = true;
cout << u;
danweinode *p = g.hnode[u].firstarc;
while(p != NULL) {
if(!visited[p -> adjvex]) {
DFS(g,p -> adjvex);
}
p = p -> nextarc;
}
//关键部分,先让指针指向头结点的第一个单位结点
//如果这个结点的adjvex没有走过,再根据这个结点的adjvex找到对应的头结点进行dfs遍历
//如果这个结点的adjvex走过,直接到下一个单位结点直到为空(null)
}
总的代码为
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
struct danweinode {
int adjvex;
struct danweinode * nextarc;
//这个指针指向单位结点的后一个结点
};
//表示头结点后面的单位结点
struct headnode {
string data;
danweinode *firstarc;
//这个是头结点,这个指针指向头结点的下一个结点
};
//定义用于存储额外信息的结构体
struct extrainfo {
headnode hnode[5];
//用于存储头结点
int vexnum;
int edgenum;
//顶点数目和边的数目
};
bool visited[5];
//走过就标记为1
void DFS(extrainfo g,int u) {
visited[u] = true;
cout << u;
danweinode *p = g.hnode[u].firstarc;
while(p != NULL) {
if(!visited[p -> adjvex]) {
DFS(g,p -> adjvex);
}
p = p -> nextarc;
}
//关键部分,先让指针指向头结点的第一个单位结点
//如果这个结点的adjvex没有走过,再根据这个结点的adjvex找到对应的头结点进行dfs遍历
//如果这个结点的adjvex走过,直接到下一个单位结点直到为空(null)
}
int main() {
visited[0] = false,visited[1] = false,visited[2] = false,visited[3] = false,visited[4] = false;
//初始化邻接表
extrainfo G;
G.vexnum = 5;G.vexnum = 8;
//5个顶点,7条边
//初始化v0头结点
G.hnode[0].data = "v0";
danweinode v1_0,v3_0,v4_0;
v1_0.adjvex = 1,v3_0.adjvex = 3,v4_0.adjvex = 4;
G.hnode[0].firstarc = &v1_0;
v1_0.nextarc = &v3_0,v3_0.nextarc = &v4_0,v4_0.nextarc = NULL;
//初始化v1头结点
G.hnode[1].data = "v1";
danweinode v0_0,v2_0,v3_1;
v0_0.adjvex = 0,v2_0.adjvex = 2,v3_1.adjvex = 3;
G.hnode[1].firstarc = &v0_0;
v0_0.nextarc = &v2_0,v2_0.nextarc = &v3_1,v3_1.nextarc = NULL;
//初始化v2头结点
G.hnode[2].data = "v2";
danweinode v1_1,v3_2,v4_1;
v1_1.adjvex = 1,v3_2.adjvex = 3,v4_1.adjvex = 4;
G.hnode[2].firstarc = &v1_1;
v1_1.nextarc = &v3_2,v3_2.nextarc = &v4_1,v4_1.nextarc = NULL;
//初始化v3头结点
G.hnode[3].data = "v3";
danweinode v0_1,v1_2,v2_1,v4_2;
v0_1.adjvex = 0,v1_2.adjvex = 1,v2_1.adjvex = 2,v4_2.adjvex = 4;
G.hnode[3].firstarc = &v0_1;
v0_1.nextarc = &v1_2,v1_2.nextarc = &v2_1,v2_1.nextarc = &v4_2,v4_2.nextarc = NULL;
//初始化v4头结点
G.hnode[4].data = "v4";
danweinode v0_2,v2_2,v3_3;
v0_2.adjvex = 0,v2_2.adjvex = 2,v3_3.adjvex = 3;
G.hnode[4].firstarc = &v0_2;
v0_2.nextarc = &v2_2,v2_2.nextarc = &v3_3,v3_3.nextarc = NULL;
cout << "邻接表的DFS结果为:";
DFS(G,3);
return 0;
}