二叉树——二叉树的遍历(递归与迭代)

二叉树的遍历中,递归版本都是利用系统提供的栈,自动将当前结点的各种信息压栈

而在迭代版本中,要自己手动的进行压栈,所以都需要一个

递归版本中,都经过结点三次

迭代版本中,都经过结点两次

 数据结构--Morris遍历--二叉树的遍历

先序遍历

public class PreOrderRecursive {
    public static void preOrderRecursive(Tree tree){
        if(tree == null) return;
        System.out.print(tree.val + " ");
        preOrderRecursive( tree.left );
        preOrderRecursive( tree.right );
    }
}

  

迭代版本:采用一个stack栈,来存放结点,有右先压右,有左后压左

 

利用栈的特性,从根部开始,依次入栈,然后依次出栈,出栈的同时,
要把它的右 左孩子(注意顺序,如果存在的话)加到栈中,直到栈中没有元素为止

 

public class PreOrderNonRecursive {

    public static void preOrderNonRecursive(Tree tree){
        if(tree == null) return;
        Stack<Tree> stack = new Stack<>();

        stack.push(tree);
        while(!stack.empty()){
            Tree subTree = stack.pop();
            System.out.print(subTree.val + " ");
            if(subTree.right != null){
                stack.push(subTree.right);
            }
            if(subTree.left != null){
                stack.push(subTree.left);
            }
        }
    }
}

 

  

 

中序遍历

public class InOrderRecursive {
    public static void inOrderRecursive(Tree tree){
        if(tree == null) return;

        inOrderRecursive(tree.left);
        System.out.print(tree.val + " ");
        inOrderRecursive(tree.right);
    }
}

  

迭代版本:

当前节点不为空,当前节点入栈,当前节点向左

只有当前节点为空时,才弹出一个节点(出栈),打印,然后当前节点向右

public class InOrderNonRecursive {
    public static void inOrderNonRecursive(Tree tree){
        if(tree == null) return;
        Stack<Tree> stack = new Stack<>();
        while(!stack.empty() || tree != null){
            //若当前结点不为空,把当前节点左子树的一排都压进来,(当前结点入栈,并且当前结点向左走)
            if(tree != null){
                stack.push(tree);
                tree = tree.left;
            } else{
                //若当前结点为空,则将栈中的一个结点弹出,并打印,然后当前结点向右走
                tree = stack.pop();
                System.out.print(tree.val + " ");
                tree = tree.right;
            }
        }
    }
}

  

后序遍历

public class PostOrderRecursive {
    public static void postOrderRecursive(Tree tree){
        if(tree == null) return;

        postOrderRecursive( tree.left );
        postOrderRecursive( tree.right );
        System.out.print(tree.val + " ");
    }
}

  

迭代版本:

因为先序遍历的顺序是 中左右, 后序遍历的顺序是 左右中

采用先序遍历的变形,首先实现一个中右左的遍历,然后将其压入辅助栈中,最后依次将辅助栈中的元素弹出即可

public class PostOrderNonRecursive {

    public static void postOrderNonRecursive(Tree tree){
        if(tree == null) return;
        Stack<Tree> stack = new Stack<>();
        Stack<Tree> stackHelp = new Stack<>();
        stack.push(tree);
        while(!stack.empty()){
            Tree subTree = stack.pop();
            stackHelp.push(subTree);
            if(subTree.left != null){
                stack.push(subTree.left);
            }
            if(subTree.right != null){
                stack.push(subTree.right);
            }
        }
        while(!stackHelp.empty()){
            System.out.print(stackHelp.pop().val + " ");
        }
    }
}

  

层序遍历

没有递归版本,只有迭代版本,借助于队列,先入先出

public class SequenceTranversal {
    public static void sequenceTranversal(Tree tree){
        if(tree == null) return;

        Queue<Tree> queue = new LinkedList<>();
        queue.offer(tree);

        while(!queue.isEmpty()){
            Tree subTree = queue.poll();
            System.out.print(subTree.val + " ");

            if(subTree.left != null){
                queue.offer(subTree.left);
            }
            if(subTree.right != null){
                queue.offer(subTree.right);
            }
        }
    }
}

  

posted @ 2018-04-25 10:52  SkyeAngel  阅读(541)  评论(0编辑  收藏  举报