关闭

二叉树的遍历

69人阅读 评论(0) 收藏 举报
分类:

最近在面试中经常被问到二叉树的相关问题,很多涉及到二叉树的问题,一个基础的解法就是遍历,所以这里简单总结一下。

本文介绍二叉树的几种遍历方式,并且用C++语言实现了一遍。其实只要稍微总结一下就可以发现,树或者图的遍历一般有两种方式,一种是用递归的方式来做,这种方法代码简洁,注意判断好边界条件就好。另外一个思路就是利用栈或者队列,这种方式写起来比较复杂,好处是效率比较高。

下面分别介绍一下:

广度优先遍历

深度优先遍历:先序遍历、中序遍历、后序遍历


1. 广度优先遍历

广度优先遍历需要用到队列,每次访问一个节点的时候,我们把它的左节点和右节点(不为空)分别放入队列。由于队列先进先出,根节点总是先于它的子节点被访问,这样就保证了一层一层的遍历节点。

void width_first_search(Tree* root)
{
	queue<Tree*> q;
	Tree* node;
	q.push(root);
	while (!q.empty()) {
		node = q.front();
		cout << node->value << " ";
		q.pop();
		if(node->left != NULL)
			q.push(node->left);
		if(node->right != NULL)
			q.push(node->right);
	}
}

2.深度优先遍历

深度优先遍历需要用到栈,每次访问一个节点,我们把它的右节点和左节点(非空)分别放入栈。由于栈是后进先出,这样就保证了根节点->左节点->右节点的遍历顺序。

下面代码里面的深度优先遍历其实就是先序遍历。

void depth_first_search(Tree *root)
{
	stack<Tree *> s;
	s.push(root);
	while (!s.empty())
	{
		root = s.top();
		cout << root->value << " ";
		s.pop();
		if (root->right != NULL)
			s.push(root->right);
		if (root->left != NULL)
			s.push(root->left);
	}
}


对于树的遍历,我们需要重点掌握上面两种遍历方式,涉及到树的题目,先想想能不能通过上面两种遍历方式或是其变形来解决。

比如,我么要查找一条深度为n的路径,这时候我们就可以用到深度优先遍历。


3. 其他遍历和实现方式

深度优先遍历包括先序、中序和后序遍历,它们的实现方式有递归和非递归两种。具体参考下面的代码。

#include <iostream>
#include <stack>
#include <queue>

using namespace std;

struct Tree
{
	int value;
	Tree* left;
	Tree* right;
	Tree() {}
	Tree(int a, Tree* pl, Tree* pr) : value(a), left(pl), right(pr) {}
};

Tree* create_tree()
{
	// 10, 7  21,  38  57  13,  62
	Tree* t_3_0 = new Tree(62, NULL, NULL);
	Tree* t_2_1 = new Tree(57, NULL, NULL);
	Tree* t_2_2 = new Tree(13, NULL, NULL);
	Tree* t_2_0 = new Tree(38, t_3_0, NULL);
	Tree* t_1_0 = new Tree(7, t_2_0, t_2_1);
	Tree* t_1_1 = new Tree(21, t_2_2, NULL);
	Tree* root = new Tree(10, t_1_0, t_1_1);
	return root;
}

void pre_order_search(Tree* root)
{
	stack<Tree*> s;
	Tree* node = root;
	while (node != NULL || !s.empty()) {
		while (node != NULL) {
			cout << node->value << " ";
			s.push(node);
			node = node->left;
		}
		if (!s.empty()) {
			node = s.top();
			s.pop();
			node = node->right;
		}
	}
}

void in_order_search(Tree* root)
{
	stack<Tree*> s;
	Tree* node = root;
	while (node != NULL || !s.empty()) {
		while (node != NULL) {
			s.push(node);
			node = node->left;
		}
		if (!s.empty()) {
			node = s.top();
			cout << node->value << " ";
			s.pop();
			node = node->right;
		}
	}
}
void pre_order_search_recursion(Tree* root)
{
	if (root != NULL)
	{
		cout << root->value << " ";
		pre_order_search_recursion(root->left);
		pre_order_search_recursion(root->right);
	}
}

void in_order_search_recursion(Tree* root)
{
	if (root != NULL)
	{
		in_order_search_recursion(root->left);
		cout << root->value << " ";
		in_order_search_recursion(root->right);
	}
}

void post_order_search_recursion(Tree* root)
{
	if (root != NULL)
	{
		in_order_search_recursion(root->left);
		in_order_search_recursion(root->right);
		cout << root->value << " ";
	}
}

void width_first_search(Tree* root)
{
	queue<Tree*> q;
	Tree* node;
	q.push(root);
	while (!q.empty()) {
		node = q.front();
		cout << node->value << " ";
		q.pop();
		if(node->left != NULL)
			q.push(node->left);
		if(node->right != NULL)
			q.push(node->right);
	}
}

void depth_first_search(Tree *root)
{
	stack<Tree *> s;
	s.push(root);
	while (!s.empty())
	{
		root = s.top();
		cout << root->value << " ";
		s.pop();
		if (root->right != NULL)
			s.push(root->right);
		if (root->left != NULL)
			s.push(root->left);
	}
}

int main()
{
	// create tree
	Tree* root;
	root = create_tree();
	// pre-order
	cout << "Result of pre-order search: ";
	pre_order_search(root);
	cout << endl;
	cout << "Result of pre-order search (recursion): ";
	pre_order_search_recursion(root);
	cout << endl;
	// in-order
	cout << "Result of in-order search: ";
	in_order_search(root);
	cout << endl;
	cout << "Result of in-order search (recursion): ";
	in_order_search_recursion(root);
	cout << endl;
	// post-order search
	cout << "Result of post-order search (recursion): ";
	post_order_search_recursion(root);
	cout << endl;
	// width first search
	cout << "Width first search: ";
	width_first_search(root);
	cout << endl;
	depth_first_search(root);
	cout << endl;
	system("pause");
	return 0;
}



1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1797次
    • 积分:94
    • 等级:
    • 排名:千里之外
    • 原创:7篇
    • 转载:3篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论