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

算法概述
递归算法简洁明了、可读性好,但与非递归算法相比要消耗更多的时间和存储空间。为提高效率,我们可采用一种非递归的二叉树遍历算法。非递归的实现要借助栈来实现,因为堆栈的先进后出的结构和递归很相似。
对于中序遍历来说,非递归的算法比递归算法的效率要高的多。其中序遍历算法的实现的过程如下:
(1).初始化栈,根结点进栈;
(2).若栈非空,则栈顶结点的左孩子结点相继进栈,直到null(到叶子结点时)退栈;访问栈顶结点(执行visit操作)并使栈顶结点的右孩子结点进栈成为栈顶结点。
(3).重复执行(2),直至栈为空。
算法实现
    package datastructure.tree;  
      
    import datastructure.stack.ArrayStack;  
    import datastructure.stack.Stack;  
      
    public class UnrecOrderBTree implements Visit{  
        private Stack stack = new ArrayStack();  
        private BTree bt;  
        @Override  
        public void visit(BTree btree) {  
            System.out.print("\t" + btree.getRootData());  
        }  
          
        public void inOrder(BTree boot) {  
            stack.clear();  
            stack.push(boot);  
            while(!stack.isEmpty()) {  
                //左孩子结点进栈  
                while((bt = ((BTree)(stack.peek())).getLeftChild()) != null) {  
                    stack.push(bt);  
                }  
                //如果该结点没有右孩子,则逐级往上出栈  
                while(!stack.isEmpty() &&!( (BTree)stack.peek() ).hasRightTree()) {  
                    bt = (BTree)stack.pop();  
                    visit(bt);  
                }  
                //如果该结点有右孩子,则右孩子进栈  
                if(!stack.isEmpty() && ( (BTree)stack.peek() ).hasRightTree()){  
                    bt = (BTree)stack.pop();  
                    visit(bt);  
                    stack.push(bt.getRightChild());  
                }  
            }  
        }  
      
    }  
测试:

package datastructure.tree;  
    /**
     * 测试二叉树
     * @author Administrator
     *
     */  
    public class BTreeTest {  
        public static void main(String args[]) {  
            BTree btree = new LinkBTree(‘A‘);  
            BTree bt1, bt2, bt3, bt4;  
            bt1 = new LinkBTree(‘B‘);  
            btree.addLeftTree(bt1);  
            bt2 = new LinkBTree(‘D‘);  
            bt1.addLeftTree(bt2);  
              
            bt3 =  new LinkBTree(‘C‘);  
            btree.addRightTree(bt3);  
            bt4 =  new LinkBTree(‘E‘);  
            bt3.addLeftTree(bt4);  
            bt4 =  new LinkBTree(‘F‘);  
            bt3.addRightTree(bt4);  
              
            RecursionOrderBTree order = new RecursionOrderBTree();  
            System.out.println("\n中序遍历:");  
            order.inOrder(btree);  
              
        }  
    }

结果如下:
中序遍历:
D B  A E
C   F

转载至:http://blog.csdn.net/luoweifu/article/details/9079799

时间: 2024-12-06 18:15:57

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

二叉树遍历的非递归

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

二叉树遍历的非递归实现

二叉树的遍历可以使用递归的方式实现,并且代码非常简单.而递归实际就是函数反复的调用本身,在栈上反复压栈.所以我们可以用栈来模拟实现递归. 1.前序遍历 (1)栈是后进先出的特点,所以无条件的把栈的根节点入栈,在把栈顶元素输出之后依次把右孩子,左孩子压入栈中. 代码如下: void _PrevOrder(Node * root) { stack<Node*> s; if (root == NULL) { return; } s.push(root);//将第一个元素入栈 while (!s.em

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

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

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

首先,要感谢网上的参考资料. 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 <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

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

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