美文网首页
二分搜索树的遍历

二分搜索树的遍历

作者: 叫我胖虎大人 | 来源:发表于2019-07-30 13:01 被阅读0次

二分搜索树的遍历和二叉树的遍历是一致的(二分搜索树的实质本身就是一棵二叉树),直接使用二叉树的遍历即可.
大一的时候数据结构学的还可以,感觉不是特别复杂

二叉树的遍历方式:

  • 深度优先遍历

1.前序遍历
2.中序遍历
3.后序遍历

  • 广度优先遍历

层序遍历


前序遍历

根节点->左孩子->右孩子

前序遍历
递归实现
/**
     * 对二叉树进行前序遍历
     */
    public void preOrder(){
        preOrder(root);
    }

    /**
     * 前序遍历的递归方式,深度优先
     * 当前节点->左孩子->右孩子
     * @param node 传入的节点
     */
    private void preOrder(Node node){
        //遍历到叶子节点时,退出当前的路线
        if (node == null){
            return;
        }

        //1.遍历当前节点
        System.out.print(node.data+"->");

        //2.遍历左孩子
        preOrder(node.left);

        //3.遍历右孩子
        preOrder(node.right);
    }

非递归实现

/**
     * 前序遍历的非递归实现方式
     */
    public void preOrderNr(){
        
        //使用栈辅助实现前序遍历
        Stack<Node> stack = new Stack<>();
        
        /*
        前序遍历的过程就是先访问当前节点,然后再访问左子树,然后再右子树
        使用栈实现的时候,可以先将当前的节点入栈 
        当前节点出站的时候,分别将右孩子,左孩子入(栈的特点:先进后出)
         */
        stack.push(root);
        //栈不为空时
        while (!stack.isEmpty()){
            Node node = stack.pop();
            //前序遍历当前的节点
            System.out.print(node.data + "->");
            
            //先进后出
            if (node.right != null){
                stack.push(node.right);
            }
            
            if (node.left != null){
                stack.push(node.left);
            }
        }

中序遍历

左孩子->根节点->右孩子

中序遍历

递归实现

/**
     * 对中序遍历进行中序遍历
     */
    public void midOrder(){
        midOrder(root);
    }

    /**
     * 中序遍历的递归方式,深度优先
     * 左孩子->当前节点->右孩子
     * @param node 传入的节点
     */
    private void midOrder(Node node){
        if (node == null){
            return;
        }

        //1.中序遍历左孩子
        midOrder(node.left);

        //2.遍历根节点
        System.out.print(node.data+"->");

        //3.遍历右孩子
        midOrder(node.right);
    }

非递归实现


    /**
     * 中序遍历的非递归实现方式
     */
    public void midOrderNr(){

        //使用栈辅助实现前序遍历
        Stack<Node> stack = new Stack<>();

        //辅助节点
        Node p = root;
        stack.add(p);

        System.err.println();
        //只要存在左孩子,就将左孩子入栈
        while (!stack.isEmpty()){
            if (p != null && p.left != null){
                stack.add(p.left);
                p = p.left;
            }else {
                p = stack.pop();
                System.out.print(p.data+"->");
                if (p != null && p.right != null){
                    //将右孩子入栈
                    stack.add(p.right);
                    p = p.right;
                }else {
                    p = null;
                }
            }
        }

后序遍历

左孩子->右孩子->根节点


后序遍历

递归实现

 /**
     * 二叉树的后序遍历
     */
    public void afterOrder(){
        afterOrder(root);
    }

    /**
     * 左孩子->右孩子->父节点
     * @param node 父节点
     */
    private void afterOrder(Node node) {
        if (node == null){
            return;
        }

        afterOrder(node.left);

        afterOrder(node.right);

        System.out.print(node.data+"->");

    }

非递归实现

/**
     * 后序遍历的非递归实现方式
     */
    public void afterOrderNr(){

       if (root != null){
           Stack<Node> stack = new Stack<>();
           stack.push(root);
           Node p;
           while (!stack.isEmpty()){
               p = stack.peek();
               if (p.left != null && root != p.left && root != p.right){
                   stack.push(p.left);
               }else if (p.right != null && root!= p.right){
                   stack.push(p.right);
               }else {
                   System.err.print(stack.pop().data+"->");
                   root = p;
               }
           }
       }
    }

层序遍历

从左到右,从上到下


层序遍历
 /**
     * 层序遍历,从左到右,从上到下,一次遍历
     * 借助队列实现
     */
    public void levelOrder(){

        Queue<Node> queue = new LinkedList<>();
        /*
         * 遍历过程:
         * 1. 首先根节点入队
         * 2. 每次出队时, 都将当前节点的左右孩子先后入队
         * 3. 如果队列为空的话, 则表示层序遍历结束
         *      5
         *    /   \
         *   3    6
         *  / \    \
         * 2  4     8
         * 针对上面的二分搜索树, 详细描述一下层序遍历步骤
         * 1. 5入队, 队列元素 : head->[5]<-tail
         * 2. 5出队, 5的左子树3, 6入队, 由于队列是先入先出(FIFO), 所以先左后右, 队列元素 : head->[3, 6]<-tail
         * 3. 3出队, 2, 4入队, 队列元素  : head->[6, 2, 4]<-tail
         * 4. 6出队, 左孩子为空,所以8入队, 队列元素  : head->[2, 4, 8]<-tail
         * 5. 2,4,8依次出队, 由于这三个节点都是叶子节点, 无子节点, 所以这三个节点出队后队列为空, 层序遍历完成
         * 6. 按照出队的顺序演示的遍历结果为 : 5 3 6 2 4 8
         */
        queue.add(root);

        while (!queue.isEmpty()){
            Node p = queue.poll();
            System.err.print(p.data+"->");
            if (p.left != null){
                queue.add(p.left);
            }
            if (p.right != null){
                queue.add(p.right);
            }
        }

小结:

相对来说非递归方式的效率会更高,但是递归方式实现逻辑更加清晰

参考博客:
https://blog.csdn.net/davidddl/article/details/75667092
https://blog.csdn.net/love905661433/article/details/82981527

相关文章

  • 二叉查找树最难的一个操作——删除

    之前的文章我们讲了二分搜索树插入、查找、深度优先遍历,以及广度优先遍历,今天我们讲二分搜索树中最难的部分——删除。...

  • 二分搜索树的遍历

    二分搜索树的遍历和二叉树的遍历是一致的(二分搜索树的实质本身就是一棵二叉树),直接使用二叉树的遍历即可.大一的时候...

  • 算法与数据结构系列之[二分搜索树-上]

    前几篇介绍了二叉树以及二叉树的遍历,接下来三篇介绍下二分搜索树。 1.什么是二分搜索树 二分搜索树(Binary ...

  • 栈 队列 queue 队列的基本应用:广度优先遍历 树;层序遍历 图;无权图的最短路径 树 二分搜索树:二叉树:

  • 递归算法复杂性分析-主定理法

    举例:1)例1:二叉树的遍历。 2)例1:归并排序。 例2:二分搜索(折半搜索)。 3)

  • Week 18 0717--0723

    question 1 逆序遍历二分树 给定一个二分搜索树(BST),对于每一个节点,加上所有比它大的节点的和,然后...

  • 手敲数据结构——二分搜索树

    使用非递归的方式进行前序遍历,借助栈的数据结构: 二分搜索树的层序遍历 问题:中序和后续遍历的非递归实现

  • 算法 | 遍历二分搜索树

    又是来自我的好朋友 EvilSay 的投稿,以下是原文: 1、基本定义 二分搜索树的每个子节点最多有两个叶子节点 ...

  • leetcode98.验证二叉搜索树

    题目链接 题目描述: 思路一:根据二叉搜索树的特性进行中序遍历 二分搜索树指的是,对于任意一个非叶节点都有:nod...

  • 5.3 删除二叉搜索树的最大元素和最小元素

    在5.2中完成了树的遍历,这一节中将对如何从二叉搜索树中删除最大元素和最小元素做介绍:我们要想删除二分搜索树的最小...

网友评论

      本文标题:二分搜索树的遍历

      本文链接:https://www.haomeiwen.com/subject/rfbirctx.html