二叉树遍历的非递归实现

二叉树的遍历可以使用递归的方式实现,并且代码非常简单。而递归实际就是函数反复的调用本身,在栈上反复压栈。所以我们可以用栈来模拟实现递归。

1.前序遍历

(1)栈是后进先出的特点,所以无条件的把栈的根节点入栈,在把栈顶元素输出之后依次把右孩子,左孩子压入栈中。

代码如下:

void _PrevOrder(Node * root)
	{
		stack<Node*> s;
		if (root == NULL)
		{
			return;
		}

		s.push(root);//将第一个元素入栈

		while (!s.empty())//当栈不为空时
		{
			root = s.top();
			cout << root->_data << "->";//打印节点
			s.pop();
			//栈的特点,后进先出,所以,先压右子树
			if (root->_right)//遍历右子树
			{
				s.push(root->_right);
			}
			if (root->_left)//遍历左子树
			{
				s.push(root->_left);
			}
		}
	}

2.中序遍历

(1)一直入栈,一直到二叉树的最左边最下边的节点。

(2)按照中序遍历的特点:左子树->根节点->右子树,输出栈顶的元素,并且弹出,必须保留该节点的指针。

(3)此时,该判断此节点的右子树:

a.右子树为NULL,返回到栈顶;

b.右子树不为NULL,把该节点当根节点,重复(1)(2)(3)......

代码如下:

	void _InOrder(Node * root)
	{
		if (root == NULL)
		{
			return;
		}
		Node * cur = root;
		stack<Node *> s;
		while (cur || !s.empty())
		{
			while (cur)//当没有左子树时,停止入栈
			{
				s.push(cur);
				cur = cur->_left;
			}
			Node * top = s.top();//保留栈顶指针,判断是否有右子树
			cout << top->_data << "->";
			s.pop();

			if (top->_right == NULL)//没有右子树时,不需要压栈
			{
				cur = NULL;
			}
			else//当存在右子树时,把右子树的根节点压入栈中,循环去判断该节点的左子树是否存在
			{
				cur = top->_right;
			}
		}
	}

3.后序遍历

(1)一直入栈,一直到二叉树的最左边最下边的节点。

(2)按照后序遍历的特点:左子树->右子树->根节点,输出栈顶的元素,并且弹出,必须保留该节点的指针。

(3)此时,该判断此节点的右子树,如果存在右子树,把该节点当作根节点,重复(1)(2)(3)

代码如下:

	void _PostOrder(Node * root)
	{
		if (root == NULL)
		{
			return;
		}
		Node * cur = root;
		Node * prev = NULL;
		stack<Node *> s;

		while (cur || !s.empty())
		{
			while (cur)//当没有左子树时,停止入栈
			{
				s.push(cur);
				cur = cur->_left;
			}

			Node * top = s.top();//保留栈顶指针,判断它的右子树是否为空或者已经出栈
			if (top->_right == NULL || top->_right == prev)
			{
				cout << top->_data << "->";
				s.pop();
				prev = top;//保留出栈元素的指针
				cur = NULL;
			}
			else//当存在右子树时,把右子树的根节点压入栈中,循环去判断该节点的左子树是否存在
			{
				cur = top->_right;
			}
		}
	}
时间: 2024-12-29 23:17:31

二叉树遍历的非递归实现的相关文章

二叉树遍历的非递归

前序遍历的非递归:1.在入栈时增加结果集,不停的取左子树入栈.直到为空.2.假设栈非空,pop栈顶结点.取其右子树作为当前结点,继续第一步.直到栈为空 中序遍历的非递归:1.在入栈时,不停的取左子树入栈,直到为空.2.假设栈非空,pop栈顶结点,增加结点集,取其右子树作为当前结点.继续第一步.直到栈为空 后序遍历的非递归:1.在遍历结点时,总是先将右子树结点入栈,再将左子树结点入栈. 2.假设左子树结点和右子树结点为空或者右子树结点已经訪问过,弹出栈顶元素,标记已訪问结点.增加结果集.直到栈为空

java数据结构之二叉树遍历的非递归实现

算法概述递归算法简洁明了.可读性好,但与非递归算法相比要消耗更多的时间和存储空间.为提高效率,我们可采用一种非递归的二叉树遍历算法.非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似.对于中序遍历来说,非递归的算法比递归算法的效率要高的多.其中序遍历算法的实现的过程如下:(1).初始化栈,根结点进栈:(2).若栈非空,则栈顶结点的左孩子结点相继进栈,直到null(到叶子结点时)退栈:访问栈顶结点(执行visit操作)并使栈顶结点的右孩子结点进栈成为栈顶结点.(3).重复执行(2),

二叉树高度,以及栈实现二叉树的先序,中序,后序遍历的非递归操作

求解二叉树的高度 树是递归定义的,所以用递归算法去求一棵二叉树的高度很方便. #include <iostream> #include <cstdio> using namespace std; struct Node { char data; Node *lchild; Node *rchild; }; void High(Node *T, int &h) { if (T == NULL) h = 0; else { int left_h; High(T->lchi

二叉树的递归遍历和非递归遍历(附详细例子)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

二叉树前序、后序和后序遍历(非递归实现)

二叉树前序.后序和后序遍历(非递归实现) (1)前序     我们知道,前序遍历的顺序是根左右,当根节点不为空时,该节点才可以被打印.目前书上常见对树的遍历都是采用递归的方法实现的,我们知道递归必然会产生中断,也就是有现场信息的保存,如果要实现非递归,那么我们必须自己要有一个栈,用来保存现场信息. 我先给出实现的伪代码,稍后我将解释为什么需要这么做,为何要用到这些条件. 伪代码如下: 1 void PreOrderTraverse(BinaryTree root) 2 { 3    Binary

二叉树基本操作续二:前序、中序、后序遍历(非递归 迭代方式)

这里给出二叉树三种遍历方式的迭代实现代码.二叉树的递归实现使用系统栈入栈出栈,而非递归的迭代实现方法就是手动维护一个栈,来模拟递归的入栈出栈过程. 本文没有给出用户栈的代码,如果需要结合上篇的测试代码一起测试,则需要自己实现自己的栈,以及基本的pop.push等栈操作函数. 前序迭代遍历: 1 void iter_preorder(tree_pointer ptr) 2 { 3 //前序遍历:先遍历根节点,然后再分别遍历左右子树 4 int top = -1; 5 tree_pointer st

二叉树遍历算法——包含递归前、中、后序和层次,非递归前、中、后序和层次遍历共八种

首先,要感谢网上的参考资料. http://mengliao.blog.51cto.com/876134/1178079(作者:BlackAlpha) http://blog.csdn.net/fzh1900/article/details/14056735(作者:_云淡风轻) http://blog.csdn.net/stpeace/article/details/8138458(作者:stpeace) 二叉树是使用的比较广泛的一种数据结构,这里我写了二叉树的相关操作,包括初始化.新建.以及遍

二叉树非递归先中后序遍历 及 非递归交换二叉树两个孩子的位置

看到一个非递归交换一个二叉树的左右孩子的位置,于是想实现之,才发现非递归的先中后序遍历都忘记了……于是杂七杂八的写了一些,抄抄资料就实现了,然后实现非递归交换两个孩子的位置还是相当容易的.先直接上代码吧,其实这东西还是得自己写写过一遍的,印象才会更加深刻: #include <iostream> #include <fstream> #include <string> #include <stack> using std::cout; using std::

【数据结构与算法】二叉树深度遍历(非递归)

据说这个笔试面试的时候非常easy考到,所以写到这里. 图示 代码实现 /** * 源代码名称:TreeIteratorNoRecursion.java * 日期:2014-08-23 * 程序功能:二叉树深度遍历(非递归) * 版权:[email protected] * 作者:A2BGeek */ import java.util.Stack; public class TreeIteratorNoRecursion { class TreeNode<T> { private T mNod