DFS(深度优先遍历)邻接表 详解

目录

实验题目

实验思路

头结点

单位结点 

额外信息 

邻接表的DFS 

总的代码为

运行结果


 

实验题目

如下图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;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柏箱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值