十八 二分搜索树的三种遍历方式

三种遍历方式:

package com.lt.datastructure.BST;

public class BST<E extends Comparable<E>> {

    private class Node{
        public E e;
        Node left,right;

        public Node(E e) {
            this.e = e;
            this.left = left;
            this.right = right;
        }

    }

    private Node root;
    private int size;

    public BST(){
        root = null;
        size = 0;
    }

    public int size() {
      return size;
    }

    public boolean isEmpty(){
        return size==0;
    }

    /*
     * 二分搜索树添加元素
     * 小于根结点,添加到左边,大于则添加到右边,等于根节点,则不作任何改变,二分搜索树不包含重复元素
     *
     */
    public void add(E e){
        //如果根节点为空
        if(root == null){
            root = new Node(e);
            size ++;
        }else{
            add(root,e);
        }
    }
    //向以root为根的二分搜索树中插入元素E,递归算法
    private Node add(Node node , E e){

        //递归的出口,找到子树为null,则必然添加,完成操作
        if(node == null){
            size++;
            return new Node(e);
        }

        if(e.compareTo(node.e)<0){
            //如果左子树为null,则node.left = new Node(e);如果不为空,继续递归
            node.left = add(node.left,e);
        }
        else if(e.compareTo(node.e)>0){
            ////如果右子树为null,则node.right = new Node(e);如果不为空,继续递归
            node.right = add(node.right,e);
        }
        //其他情况,比如元素相等,则返回传进来的根节点,不做操作
        return node;
    }

    //查询二分搜索树中是否包含元素e
    public boolean contains(E e){
        return contains(root,e);
    }
    //看以node为根的二分搜索树中是否含有元素e,递归实现
    private boolean contains(Node node , E e){
        if(node == null){
            return false;
        }

        if(e.compareTo(node.e)==0){
            return true;
        }
        else if(e.compareTo(node.e)<0){
            return contains(node.left,e);
        }else{
            return contains(node.right,e);
        }
    }

    /*
     * 二分搜索树的前序遍历(先访问结点,再访问左,右子树),最自然,最常用的遍历方式
     *
     * */
    public void preOrder(){
        preOrder(root);
    }

    private void preOrder(Node node){
        //递归终止
        if(node==null){
            return;
        }
        //递归调用
        System.out.println(node.e);//首先打印根节点
        preOrder(node.left);//然后递归left,直到left为空,回溯,打印left由深到浅
        preOrder(node.right);//最后递归完了left,递归right,right打印由浅到深

    }

    //遍历的展示
    @Override
    public String toString() {
        StringBuilder res = new StringBuilder();
        BSTString(root,0,res);
        return res.toString();
    }
    //生成以node为根节点,深度为depth描述的字符串
    private void BSTString(Node node, int depth, StringBuilder res) {
        if(node==null){
            res.append(DepthString(depth)+"null\n");
            return;
        }

        res.append(DepthString(depth)+node.e+"\n");
        BSTString(node.left,depth+1,res);
        BSTString(node.right, depth+1, res);
    }

    private String DepthString(int depth) {
        StringBuilder res = new StringBuilder();
        for(int i=0; i<depth ; i++){
            res.append("--");
        }
        return res.toString();
    }
    /*
     * 二分搜索树的中序遍历(访问左子树,结点,右子树),顺序由小到大,最自然,最常用的遍历方式
     * */
    public void inOrder(){
        inOrder(root);
    }

    //中序遍历以node为根的二分搜索树,递归算法
    private void inOrder(Node node){
      if(node==null){
          return;
      }
      inOrder(node.left);//由深到浅打印left
      System.out.println(node.e);//每递归一次,打印当前根节点
      inOrder(node.right);//由浅到深打印right
    }
    /*
     * 二分搜索树的后序遍历(访问右子树,左子树,结点),最自然,最常用的遍历方式
     * */
    public void postOrder(){
        postOrder(root);
    }

    private void postOrder(Node node) {
        //递归的终点
        if(node == null){
            return;
        }    

        postOrder(node.left);//打印right由深到浅
        postOrder(node.right);//打印left由深到浅
        System.out.println(node.e);//最后打印根节点
    }
    /*
     * 先序中序后序遍历的打印特点:
     *   对于每个结点,都有三次访问,可以用三个点代表三次操作。
     *   先序遍历:打印发生在第一此访问。
     *   中序遍历:打印发生在第二次访问。
     *   后序遍历:打印发生在第三次访问。
     */
}

测试代码:

package com.lt.datastructure.BST;
/*
 * Binary Search Tree
 */
public class Main {
    public static void main(String[] args) {
        BST<Integer> bst = new BST<>();
        int[] nums = {5,3,6,8,4,2};
        for(int num : nums){
            bst.add(num);
        }
        bst.postOrder();
        System.out.println();

        bst.preOrder();
        System.out.println();

        bst.inOrder();
        System.out.println();
    }
}

三种遍历的输出结果:

先序遍历:

中序遍历:

后序遍历:

三种遍历的打印顺序:

先序中序后序遍历的打印特点:

  • 对于每个结点,都有三次访问,可以用三个点代表三次操作。
  • 先序遍历:打印发生在第一此访问。
  • 中序遍历:打印发生在第二次访问。
  • 后序遍历:打印发生在第三次访问。

原文地址:https://www.cnblogs.com/ltfxy/p/10004193.html

时间: 2024-10-17 22:41:33

十八 二分搜索树的三种遍历方式的相关文章

重温数据结构:二叉树的常见方法及三种遍历方式 Java 实现

读完本文你将了解到: 什么是二叉树 Binary Tree 两种特殊的二叉树 满二叉树 完全二叉树 满二叉树 和 完全二叉树 的对比图 二叉树的实现 用 递归节点实现法左右链表示法 表示一个二叉树节点 用 数组下标表示法 表示一个节点 二叉树的主要方法 二叉树的创建 二叉树的添加元素 二叉树的删除元素 二叉树的清空 获得二叉树的高度 获得二叉树的节点数 获得某个节点的父亲节点 二叉树的遍历 先序遍历 中序遍历 后序遍历 遍历小结 总结 树的分类有很多种,但基本都是 二叉树 的衍生,今天来学习下二

树的高度,深度,层数和三种遍历方式

树的高度: 当只有一个根节点的时候,高度就是0. //计算树的高度int depth(Node node){ if(node == NULL) return -1; int l = depth(node->left); int r = depth(node->right); return (l < r)?(r+1):(l+1);//当只有一个根节点的时候,高度就是-1+1=0} 层数: 树的高度最底下的为第1层(有的书定义为第0层),依次向上累加 树的深度: 完全二叉树是指这样的二叉树:

二叉树的三种遍历方式的循环和递归的实现方式

///////////////////头文件:BST.h//////////////////////// #ifndef BST_H #define BST_H #include "StdAfx.h" #include<iostream> #include<stack> template<typename DataType> class BST { public: class Node { public: Node(int data=0):m_dat

set的三种遍历方式-----不能用for循环遍历(无序)

set的三种遍历方式,set遍历元素 list 遍历元素 http://blog.csdn.net/sunrainamazing/article/details/71577662 set遍历元素 http://blog.csdn.net/sunrainamazing/article/details/71577893 map遍历元素 http://blog.csdn.net/sunrainamazing/article/details/71580051 package sun.rain.amazi

for 、foreach 、iterator 三种遍历方式的比较

习惯用法 for.foreach循环.iterator迭代器都是我们常用的一种遍历方式,你可以用它来遍历任何东西:包括数组.集合等 for 惯用法: List<String> list = new ArrayList<String>(); String[] arr = new String[]{"1,2,3,4"}; for(int i = 0;i < arr.length;i++){ System.out.println(arr[i]); } for(i

java中ArrayList集合的三种遍历方式

public class ListDemo { public static void main(String[] args) { ArrayList<String> mList = new ArrayList<>(); mList.add("郭靖"); mList.add("黄蓉"); mList.add("洪七公"); mList.add("周伯通"); // 第一种遍历方式:普通for循环 for

有关不同实现类的List的三种遍历方式的探讨

我们知道,List的类型有ArrayList和LinkedList两种,而曾经的Vector已经被废弃. 而作为最常用的操作之一,List的顺序遍历也有三种方式:借助角标的传统遍历.使用内置迭代器和显式迭代器. 下面,将首先给出两种种不同类型实现的实验结果,之后,将会通过分析JAVA中List的各种实现,来探讨造成实验结果的原因. 1.随机数据的生成 package temp; import java.io.*; import java.util.Random; public class Dat

完全二叉树的三种遍历方式

二叉树的遍历方法有多种,最常用的有中序遍历.先序遍历和后序遍历.毫无例外,这三种遍历方法都是基于递归/迭代的思想 为了更好的说明三种遍历,结合图片. 假设现在存在{1,3,5,7,9,2,4,6,8,10}的一个完全二叉树 中序遍历:遍历时先尝试访问当前结点的左子结点,如果左子结点不存在,则读取当前结点的数据,然后再访问当前结点的右子结点.对应的遍历结果是:6 7 8 3 10 9 1 2 5 4 先序遍历:遍历时先读取当前结点的数据,然后在访问当前结点左子结点.仅当左子结点不存在,则访问右子结

Java学习(十八):二叉树的三种递归遍历

二叉树的三种递归遍历: 1 public class StudentNode 2 { 3 private String name; 4 5 private StudentNode leftNode; 6 7 private StudentNode rightNode; 8 9 public String getName() 10 { 11 return name; 12 } 13 14 public void setName(String name) 15 { 16 this.name = na