二叉树遍历算法(Binary Tree)

二叉树遍历算法主要包括递归遍历方式、非递归遍历方式。而每一种方式又分为先序遍历、中序遍历、后序遍历。如果你的二叉树是二叉排序树,希望遍历出来的结果是有序的,那么无论是递归还是飞递归都需要使用中序遍历。另外,有时,我们也需要对二叉树进行层序遍历。假设二叉树结构如下:

树的构建代码如下:

#include <iostream>

struct BiNode 
{
	char ch;
	BiNode* lchild;
	BiNode* rchild;
};

int main()
{
	//创建结点
	BiNode node1, node2, node3, node4, node5, node6, node7, node8;
	node1.ch = 'A'; node1.lchild = nullptr; node1.rchild = nullptr;
	node2.ch = 'B'; node2.lchild = nullptr; node2.rchild = nullptr;
	node3.ch = 'C';	node3.lchild = nullptr; node3.rchild = nullptr;
	node4.ch = 'D';	node4.lchild = nullptr; node4.rchild = nullptr;
	node5.ch = 'E';	node5.lchild = nullptr; node5.rchild = nullptr;
	node6.ch = 'F';	node6.lchild = nullptr; node6.rchild = nullptr;
	node7.ch = 'G';	node7.lchild = nullptr; node7.rchild = nullptr;
	node8.ch = 'H';	node8.lchild = nullptr; node8.rchild = nullptr;

	//建立结点关系
	node1.lchild = &node2;
	node1.rchild = &node6;
	node2.rchild = &node3;
	node3.lchild = &node4;
	node3.rchild = &node5;
	node6.rchild = &node7;
	node7.lchild = &node8;

	return 0;
}

1. 二叉树递归遍历

我们接下来编码实现其递归遍历:

// 先序遍历
void recursion_traversal(BiNode* root) 
{
	if (root == NULL) 
	{
		return;
	}
	printf("%c", root->ch);
	recursion_traversal(root->lchild);
	recursion_traversal(root->rchild);
}

// 中序遍历
void recursion_traversal(BiNode* root) 
{
	if (root == NULL) 
	{
		return;
	}
	recursion_traversal(root->lchild);
	printf("%c", root->ch);
	recursion_traversal(root->rchild);
}

// 后序遍历
void recursion_traversal(BiNode* root) 
{
	if (root == NULL) 
	{
		return;
	}
	
	recursion_traversal(root->lchild);
	recursion_traversal(root->rchild);
	printf("%c", root->ch);
}

2. 二叉树非递归遍历

二叉树非递归遍历算法需要借助栈容器的辅助。

void non_recursion_traversal(BiNode* root)
{

	// 根节点入栈
	std::stack<std::pair<bool, BiNode*>> stack;
	stack.push(std::make_pair(false, root));

	while (!stack.empty())
	{
		// 弹出栈顶元素
		auto element = stack.top();
		stack.pop();

		// 如果栈顶元素标记为 true 则直接输出
		if (element.first)
		{
			std::cout << element.second->ch << " ";
			continue;
		}

		// 如果栈顶元素标记为 false, 则按下面的规则再次进行入栈操作
		/*
		* 如果先序遍历,则入栈顺序为:右、左、根
		* 如果中序遍历,则入栈顺序为:右、根、左
		* 如果后序遍历,则入栈顺序为:根、右、左
		* 注意: 根节点第二次入栈时,需要将其 first 属性修改为 true
		*/

		// 右结点
		if (element.second->rchild != nullptr)
		{
			stack.push(std::make_pair(false, element.second->rchild));
		}
		
		// 左结点
		if (element.second->lchild != nullptr)
		{
			stack.push(std::make_pair(false, element.second->lchild));
		}

		// 根节点
		element.first = true;
		stack.push(element);
	}
}

程序输出结果:

A B C D E F G H

3. 二叉树层序遍历

二叉树的层序遍历需要借助队列容器的辅助。层序遍历顾名思义,就是从上向下,从左向右一层一层的遍历二叉树中的每个元素。

void level_traversal(BiNode* root)
{

	// 根节点入栈
	std::queue<BiNode *> queue;
	queue.push(root);

	while (!queue.empty())
	{
		// 弹出队头元素
		auto element = queue.front();
		queue.pop();

		// 打印队头元素
		std::cout << element->ch << " ";

		// 将当前根节8点的左右子结点入队列
		if (element->lchild != nullptr)
		{
			queue.push(element->lchild);
		}

		// 左结点
		if (element->rchild != nullptr)
		{
			queue.push(element->rchild);
		}
	}
}

程序输出结果:

A B F C G D E H
未经允许不得转载:一亩三分地 » 二叉树遍历算法(Binary Tree)