IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 《算法笔记》读书记录DAY_34 -> 正文阅读

[数据结构与算法]《算法笔记》读书记录DAY_34

CHAPTER_9? 提高篇(3)——数据结构(2)

9.3.4 从树的遍历看DFS和BFS

深度优先搜索与先根遍历

回忆树的先根遍历,我们会发现先根遍历就是DFS的过程。实际上,对所有合法的DFS过程,都哦可以把他画成树的形式,此时递归边界等价于树的叶子节点,而分岔口等价于树的非叶子节点。

于是我们可以从中得到一些启发:碰到一些可以用DFS的题目,不妨把一些状态作为树的结点。然后问题就会转化为对树的先根遍历。如果想要得到树的某些信息,也可以借用DNFS以深度作为第一关键词进行遍历。例如求解叶子节点的带权路径和时就可以把到达叶子节点作为一条路径结束的判断。

广度优先搜索与层序遍历

树的层序遍历,和BFS同样有着相同的思想。对于所有合法的BFS求解过程,也可以像DFS那样画出一棵树,并且将其转化为树的层次遍历。

下面我们通过一个例题来练习这一思想。

题目:

给定一棵树和每个节点的权值,求所有从根节点到叶子节点的路径中,使得每条路径上的节点权值之和等于给定常数S的路径。如果有多条这样的路径,则按路径非递增的顺序输出。其中路径大小是指,如果两条分别为a1-a2-...-ai-an与b1-b2-...-bi-bm,且有a1=b1,a2=b2,...,ai-1=bi-1成立,但ai>bi,则称第一条路径比第二条路径大。

输入格式:

每个输入包含一个测试用例。每个测试用例在第一行给出节点个数N,非叶子节点的个数M,给定常数S。其中0<N<=100,M<N,S<2^30。第二行给出N个正数,对应着N个节点的权重。接下来有M行,每行给出每个非叶子节点的具体信息:节点编号、子节点个数、每个子节点的编号。

输出格式:

输出权值和等于S的所有路径。输出路径上每个节点的权值即为输出路径(每个权值用空格分隔),每个路径占一行,并按非递增排序。

输入样例:

20 9 24

10 2 4 3 5 10 2 18 9 7 2 2 1 3 12 1 8 6 2 2

00 4 01 02 03 04

02 1 05

04 2 06 07

03 3 11 12 13

06 1 09

07 2 08 10

16 1 15

13 3 14 16 17

17 2 18 19

输出样例:

10 5 2 7

10 4 10

10 3 3 6 2

10 3 3 6 2??

思路:

我们采用树的静态写法来存储节点,并根据输入格式来将节点连接成树。然后设置int型数组path记录递归过程中产生的节点编号。然后开始DFS递归,参数有3个:当前访问节点index、当前路径节点个数nodeNum、当前权值和sum。递归过程如下:

(1)如果sum>S,直接退出;

(2)如果sum==S且当前节点为叶子节点,说明已经达到符合条件的路径,输出path中所有数? ? ? ? ? ? ? ?据;如果sum==S但当前不是叶子节点,直接退出;

(3)如果sum<S,说明还可以往下递归。遍历当前节点的所有子节点,对每一个子节点将其存入? ? ? ? ? ?path,然后往下递归。

通过上面的算法,我们能将所有权值和等于S的路径输出。但是,我们还没有解决路径的排序输出问题。路径排序输出的方法十分巧妙,我们在读入每个节点的所有子节点之后(即输入每行节点的具体信息之后),对该节点的vector进行非递减排序。通过这么排序,DFS的输出路径就自然而然地变为非递减排序路径了。(不妨手动模拟vector排序后的DFS体会其过程)

参考代码:?

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;
const int maxn=101;
int n,m,s;                     //节点个数、非叶子节点个数、常数S
int path[maxn]={0};

struct Node {                  //定义树节点 
	int data;
	vector<int> child;
}node[maxn];

bool cmp(int a,int b) {
	return node[a].data>node[b].data;
}

void DFS(int index,int nodeNum,int sum) {
	sum+=node[index].data;                             //更新当前和 
	nodeNum++;                                         //结点数+1 
	path[nodeNum]=index;                               //将当前节点加入路径 
	if(sum>s)                                          //当前和大于s,退出 
		return;
	else if(sum==s) {                                  //当前和等于s 
		if(node[index].child.size()!=0) {              //当前非叶子节点 
			return;
		}
		else {                                         //当前叶子节点 
			for(int i=1;i<=nodeNum;i++) {              //控制格式输出path中的节点权值 
				if(i==nodeNum)
					cout<<node[path[i]].data<<endl;
				else
					cout<<node[path[i]].data<<' ';
			}
			return;
		}
	}
	else {                                             //当前和小于叶子节点,往下递归 
		for(int i=0;i<node[index].child.size();i++) {  //遍历所有子节点
			DFS(node[index].child[i],nodeNum,sum);     //递归至下一轮 
		} 
	}
}

int main() {
	int id,k,tmp;                 //id接收节点编号,k记录节点孩子个数
	cin>>n>>m>>s;
	for(int i=0;i<n;i++) {        //输入每个节点的权重 
		cin>>node[i].data;
	}
	for(int i=0;i<m;i++) {        //输入每个节点的具体信息 
		cin>>id>>k;
		for(int j=0;j<k;j++) {
			cin>>tmp;
			node[id].child.push_back(tmp);
		}
		sort(node[id].child.begin(),node[id].child.end(),cmp);   //对子节点按权值排序 
	}
	DFS(0,0,0);                   //从根节点开始,初始状态节点个数0,和为0 
	return 0;
}

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-22 11:11:28  更:2021-10-22 11:12:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:49:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码