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


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

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

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

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

     数据结构--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);
                }
            }
        }
    }
    

      

  • 相关阅读:
    gitlab+gerrit+jenkins持续集成框架
    多线程自动翻页爬虫
    爬虫超级简单入门
    完整开发流程管理提升与系统需求分析过程 随堂笔记(day 1) 【2019/10/14】
    Logistic Regression
    cmdb项目-2
    cmdb项目-3
    cmdb全总结
    crm-1
    crm-2
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/8940865.html
Copyright © 2020-2023  润新知