【知识点3】树的遍历

树的静态写法

一般意义上的“树”与“二叉树”不太一样,它的子结点的个数是不限的,而是子结点没有先后次序。

这里我们建议在考试中使用树的静态写法来表述树,也就是用数组下标来代替所谓的地址:

struct node{
	typename data;
	int child[maxn];
}Node[maxn]; 

在上面的定义中,由于无法预知子结点个数,因此child数组的长度只能开到最大,我们其实可以使用STL中的vector来代替固定长度数组。

struct node{
	typename data;
	vector child;
}Node[maxn];

与二叉树的静态实现类似,当需要新建一个结点时,就按顺序从数组中取一个下标即可,如下所示:

int index = 0;
int newNode(int v){
	Node[index].data = v;
	Node[index].child.clear();
	return index++;
} 

不过在考试中涉及树(非二叉树)时,一般都会很人性化地给出结点的编号,因此我们可以直接使用这些编号作为数组的下标。

需要特别指出,如果题目中不涉及结点的数据域,只需要树的结构,那么我们并不需要结构体,可以直接使用vector<int> child[maxn]

树的先根遍历

在这里插入图片描述

void PreOrder(int root){
	printf("%d ",Node[root].data);
	for(int i=0;i<Node[root].child.size();i++){
		PreOrder(Node[root].child[i]);
	}
}

树的层序遍历

树的层次遍历与二叉树的层次遍历类似。

void LayerOrder(intb root){
	queue<int> Q;
	Q.push(root);
	
	while(!Q.empty()){
		int front = Q.front();
		printf("%d ",Node[front].data);
		Q.pop();
		for(int i=0;i<Node[front].child.size();i++){
			Q.push(Node[front].child[i]);
		}
	}
}

同样的,如果需要对结点的层号进行求解,只需要在结构体node的定义中增加变量来记录结点的层号。

struct node{
	int layer;
	int data;
	vector<int> child;
};

于是树的层序遍历就可以写成下面这样:

void LayerOrder(intb root){
	queue<int> Q;
	Q.push(root);
	Node[root].layer = 0;	
	while(!Q.empty()){
		int front = Q.front();
		printf("%d ",Node[front].data);
		Q.pop();
		for(int i=0;i<Node[front].child.size();i++){
			Node[child].layer = Node[front].layer + 1;
			Q.push(Node[front].child[i]);
		}
	}
}

从树的遍历看DFS和BFS

深度优先搜索(DFS)与先根遍历

其实这里讲的就是一个 回溯树 的概念。

我们在讲解深度优先搜索时举了迷宫的例子,其实我们可以将迷宫的岔道口和死胡同都当作结点,并将它们的连接关系表示出来,就会得到图9-16所示的这棵树:
在这里插入图片描述
事实上,对所有合法的DFS求解过程,都可以把它画成树的形式,此时死胡同等价于树中的叶子结点,而岔道口等价于树中的非叶子结点,并且对这棵树的DFS遍历过程就是树的先根遍历的过程。

于是可以从中得到启发:碰到一些可以用DFS做的题目,不妨把一些状态作为树的结点,然后问题就会转换为直观的对树进行先根遍历的问题。

广度优先搜索(BFS)与层序遍历

在使用BFS模拟迷宫问题的过程中,依然将迷宫的岔道口和死胡同都简化为结点,将迷宫的结构转换为树。借用上面得到的迷宫树形图,如果模仿层序遍历的方法来遍历这棵树,就可以得到当初BFS过程中得到的序列。

题型训练

【PAT A1053】Path of Equal Weight
【PAT A1079】Total Sales of Supply Chain
【PAT A1090】Highest Price in Supply Chain
【PAT A1094】The Largest Generation
【PAT A1106】Lowest Price in Supply Chain
【PAT A1004】Counting Leaves

参考文档

算法笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值