【数据结构实验】图的深度优先搜索(DFS)生成树
创作时间:
作者:
@小白创作中心
【数据结构实验】图的深度优先搜索(DFS)生成树
引用
1
来源
1.
https://cloud.tencent.com/developer/article/2440462
深度优先搜索(DFS)是图算法中一种重要的遍历方法,通过深度遍历图的顶点来构建生成树。本文将通过C语言实现深度优先搜索生成树,帮助读者理解DFS算法的具体实现过程。
1. 引言
深度优先搜索(DFS)是图算法中的一种重要的遍历方法,它通过深度遍历图的顶点来构建生成树。生成树是一个无回路的连通子图,包含了原图的所有顶点,但是边数最少。
本实验将通过C语言实现深度优先搜索生成树。
2. 深度优先搜索生成树
深度优先搜索是一种递归的图遍历算法,其主要思想是从起始顶点开始,尽可能深入图中的每一个分支,直到不能再深入为止,然后回溯到上一个分支。
3. 实验内容
3.1 实验题目
以顶点 0 为起始顶点,求图 G 的深度优先搜索生成树(即深度优先遍历过程形成的树)。
(一)输入要求
int A[N][N] = {
{0, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0}
};
使用前文得到的邻接表做为输入数据
(二)输出要求
输出树中所有结点。结点输出格式如下:(顶点,顶点的父亲,顶点所在的层数)比如,对下面这棵树,有以下输出。
3.2 算法实现
- 数据结构
typedef struct P {
int VerAdj;
struct P *link;
} P;
typedef struct Q {
int VerName;
P *Adjacent;
int Visited;
} Q;
typedef struct {
Q Head[20];
} Graph;
typedef struct Tree {
Q data;
struct Tree *FirstChild;
struct Tree *NextBrother;
} Tree;
typedef struct q {
Tree *data;
struct q *next;
} Queue;
- P结构体:用于表示图中的邻接点,
- VerAdj 表示邻接顶点,
- link 指向下一个邻接点。
- Q结构体:用于表示图中的顶点,
- VerName 表示顶点名称,
- Adjacent 指向邻接点链表,
- Visited 表示是否被访问过。
- Graph结构体:表示整个图,包含一个数组 Head,每个元素表示一个顶点。
- Tree结构体:表示生成树中的节点,包含一个数据域 data,表示顶点,以及 FirstChild 和 NextBrother 分别指向第一个孩子和下一个兄弟节点。
- Queue结构体:用于实现队列,存储生成树的节点。
- 队列操作函数
void QInsert(Tree *item);
void QDelete();
- QInsert:将生成树节点插入队列。
- QDelete:从队列中删除节点。
- 广度优先搜索遍历
void LevelOrder(Tree *t);
- LevelOrder:广度优先搜索遍历生成树,输出节点信息,包括顶点、父亲和层数。
- 创建图
void Create(Graph *g);
- Create:根据邻接矩阵 A 创建图,构建邻接表。
- 深度优先搜索算法
void DepthForceSearch(Graph *g, int i, Tree *t);
- DepthForceSearch:递归实现深度优先搜索,构建生成树。
- 主函数及DFS主函数
int main();
void DFS_Main(Graph *g, Tree *t);
- main函数:创建图,调用DFS_Main进行深度优先搜索,输出生成树的节点信息。
- DFS_Main:遍历所有未访问的顶点,以每个未访问的顶点为根进行深度优先搜索。
- 输出生成树信息
void Output(Tree *t);
- Output:输出生成树的节点信息。
3.3 代码整合
#include <stdio.h>
#include <stdlib.h>
#define N 7
int A[N][N] = {
{0, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0}
};
typedef struct P {
int VerAdj;
struct P *link;
} P;
typedef struct Q {
int VerName;
P *Adjacent;
int Visited;
} Q;
typedef struct {
Q Head[20];
} Graph;
typedef struct Tree {
Q data;
struct Tree *FirstChild;
struct Tree *NextBrother;
} Tree;
typedef struct q {
Tree *data;
struct q *next;
} Queue;
Queue *front = NULL, *rear = NULL, *pos = NULL;
void QInsert(Tree *item);
void QDelete();
void LevelOrder(Tree *t);
void Create(Graph *g);
void DepthFirstSearch(Graph *g, int i, Tree *t);
void DFS_Main(Graph *g, Tree *t);
void Output(Tree *t);
int main() {
Graph g;
Tree t;
Create(&g);
printf("深度遍历:\n");
DFS_Main(&g, &t);
printf("生成树结点信息:\n");
Output(&t);
return 0;
}
void QInsert(Tree *item) {
Queue *s = (Queue *)malloc(sizeof(Queue));
s->data = item;
s->next = NULL;
if (front == NULL)
front = s;
else
rear->next = s;
rear = s;
}
void QDelete() {
if (front == NULL) {
printf("队列为空");
return;
}
Queue *p = front;
front = p->next;
free(p);
if (front == NULL)
rear = NULL;
}
void LevelOrder(Tree *t) {
if (t != NULL)
QInsert(t);
while (front != NULL) {
Tree *p = front->data;
printf("(%d, %d, %d) ", p->data.VerName, t->data.VerName, p->data.VerName);
while (p != NULL) {
if (p->FirstChild != NULL) {
QInsert(p->FirstChild);
}
p = p->NextBrother;
}
QDelete();
}
}
void Create(Graph *g) {
int i, j, n, t;
for (i = 0; i < N; i++) {
g->Head[i].VerName = i;
g->Head[i].Adjacent = NULL;
P *p = (P *)malloc(sizeof(P));
t = 0;
for (j = 0; j < N; j++) {
if (A[i][j]) {
if (t == 0) {
g->Head[i].Adjacent = p;
p->VerAdj = j;
p->link = NULL;
t = 1;
} else {
P *q = (P *)malloc(sizeof(P));
q->VerAdj = j;
q->link = NULL;
p->link = q;
p = q;
}
}
}
}
}
void Output(Tree *t) {
if (t != NULL)
LevelOrder(t);
}
void DepthForceSearch(Graph *g, int i, Tree *t) {
P *p;
g->Head[i].Visited = 1;
p = g->Head[i].Adjacent;
t->data = g->Head[i];
while (p != NULL) {
if (!g->Head[p->VerAdj].Visited) {
Tree *child = (Tree *)malloc(sizeof(Tree));
child->NextBrother = NULL;
child->FirstChild = NULL;
DepthForceSearch(g, p->VerAdj, child);
Tree *temp = t->FirstChild;
if (temp == NULL) {
t->FirstChild = child;
} else {
while (temp->NextBrother != NULL) {
temp = temp->NextBrother;
}
temp->NextBrother = child;
}
}
p = p->link;
}
}
void DFS_Main(Graph *g, Tree *t) {
int i;
for (i = 0; i < N; i++)
g->Head[i].Visited = 0;
for (i = 0; i < N; i++) {
if (!g->Head[i].Visited) {
Tree *root = (Tree *)malloc(sizeof(Tree));
root->NextBrother = NULL;
root->FirstChild = NULL;
DepthForceSearch(g, i, root);
*t = *root;
}
}
}
4. 实验结果
通过上述代码实现,可以得到图 G 的深度优先搜索生成树。实验结果展示了如何从顶点 0 开始,通过深度优先搜索算法构建生成树,并输出生成树中所有节点的信息。
热门推荐
如何写对产品的需求建议
虚拟现实与情感共鸣,探索角色扮演类游戏的深度体验
阳台洗衣机柜材质选择指南:14种常见材质优缺点全解析
通过组策略设置域用户锁定后多久自动解锁
什么是职业规划?当前经济大形势下,有必要做职业规划吗?
公办学校和民办学校最大的差距,其实是这几点
哪些是公务员面试结尾的金句?
传统寿诞习俗之周岁礼俗 抓周的渊源和礼俗
银行七天通知存款是什么?有哪些优缺点?
这届年轻人正在集体"断亲"?"断亲"背后,年轻人反感的究竟是什么?
干燥、感冒来袭,别慌,这里有超强应对攻略!
中原文化+岭南文化 湖南耒阳这个东汉古墓不一般!
【语文大师】十五从军征——古诗十九首
股票异动次数查看:如何查看股票几次异动
叶酸加维生素B12,该组合的3大作用,一定要知道!
食管解剖及影像图解【秒懂收藏级】
翡翠手镯买了可以退货吗?怎么退?多少钱?现在能退吗?
魔域口袋版异能者觉醒攻略
绘画色彩中的色块:定义、表现方法与艺术魅力
“急急如律令” 翻译成“swift and uplift”,你怎么看?
陶瓷脏了的清洁方法有哪些?如何选择合适的清洁工具和材料?
什么是数据工程?其在医疗行业的应用有哪些?
去不了远方,就去一趟江南吧,到杭州这6个地方,看浪漫春色
容易养殖的球兰品种,以及容易养殖的球兰品种有哪些
KDJ指标在股票中的应用是什么?如何正确使用KDJ指标进行投资决策?
代糖是什么?有坏处会致癌?认识人工甜味剂的利与弊
如何通过社保官网了解最新的社保政策?
探索香港科技类公司的发展空间:全面解析经营范围及其潜力
软件开发需要学习哪些技术
在欧盟旅行,可以携带多少烟酒?