Bootstrap

从0实现二叉树的存储与遍历

1.1链式存储
第⼀⾏⼀个整数n,表⽰结点数。
之后n⾏,第⾏两个整数l 、r,分别表⽰结点i的左右⼦结点编号。若l=0则表⽰⽆左
⼦结点,同理。

#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int l[N];
int r[N];
int main()
{
	int n = 0;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		// 存下 i 号结点的左右孩⼦
		cin >> l[i] >> r[i];
	}
	return 0;
}

2.二叉树的遍历
2.1 深度优先遍历
不同于常规树的深度优先遍历,⼆叉树因其独特的性质可以划分成三种深度优先遍历:先序遍历,中序遍历,和后序遍历。其中,三种遍历⽅式的不同在于处理根节点的时机。
对于⼀棵⼆叉树⽽⾔,整体可以划分成三部分:根节点+左⼦树+右⼦树:
• 先序遍历的顺序为:根+左+右;
• 中序遍历的顺序为:左+根+右;
• 后序遍历的顺序为:左+右+根。

#include<iostream>
using namespace std;
const int N = 1e5 + 10;
int l[N];
int r[N];
void dfs1(int u)
{
	
	if (u == 0)return;
	cout << u;
	dfs1(l[u]);
	dfs1(r[u]);
}

void dfs2(int u)
{

	if (u == 0)return;
	dfs2(l[u]);
	cout << u;
	dfs2(r[u]);
}

void dfs3(int u)
{

	if (u == 0)return;
	dfs3(l[u]);
	dfs3(r[u]);
	cout << u;
}

int main()
{
	int n = 0;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		// 存下 i 号结点的左右孩⼦
		cin >> l[i] >> r[i];
	}
	dfs1(1);//先序
	dfs2(1);//中序
	dfs3(1);//后序
	return 0;
}

2.2 宽度优先遍历
这个就和常规的树的遍历⽅式⼀样,直接⽤队列帮助层序遍历即可。

#include<iostream>
#include<queue>
using namespace std;
const int N = 1e5 + 10;
int l[N];
int r[N];
void bfs()
{
	queue<int>q;
	q.push(1);
	while (q.size())
	{
		auto p = q.front(); q.pop();
		cout << p;
		// 左右孩⼦⼊队
		if (l[p]) q.push(l[p]);
		if (r[p]) q.push(r[p]);
	}
	cout << endl;
}
int main()
{
	int n = 0;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> l[i] >> r[i];
	}
	bfs();
	return 0;
}

下一篇堆

;