20191214-二叉查找树(BST)

二叉查找树(BST)

定义:

二叉查找树(Binary Search Tree),又被称为二叉搜索树。设x为二叉查找树中的一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]

特性:

  • 1、 子树上所有结点的值均 小于或等于 它的根结点的值。
  • 2、 子树上所有结点的值均 大于或等于 它的根结点的值。
  • 3、左、右子树也分别为 二叉排序树
  • 4、 没有 键值相等的节点(no duplicate nodes)。

在这里插入图片描述

二分查找思想: 以查找值为 10 的节点为例

1、查看根节点 9
在这里插入图片描述
2、由于 10>9, 因此查看右孩子 13:
在这里插入图片描述

3、由于 10<13 ,因此查看左孩子 11:

在这里插入图片描述

4、由于 10<11 ,因此查看左孩子10,发现10正是要查找的节点:

在这里插入图片描述

查找所需的最大次数==二叉查找树的高度!!

二叉查找树的Java实现

  • BSTree是二叉树,它保护了二叉树的根结点mRoot;

  • mRoot是BstNode类型,而BstNode是二叉查找树的结点,它是BSTree的内部类

  • 二叉查找树的节点BstNode包含二叉查找树的几个基本信息:

  1. key – 它是关键字,是用来对二叉查找树的节点进行排序的。
  2. left – 它指向当前节点的左孩子。
  3. right – 它指向当前节点的右孩子。
  4. parent – 它指向当前节点的父结点。
/**
 * @Description: 描述
 * @Author: llf
 * @CreateDate: 2019/12/14 16:03
 *
 * <T extends  Comparable<T>>:类型 T 必须实现 Comparable 接口,并且这个接口的类型是 T。只有这样,T 的实例之间才能相互比较大小。
 *
 */
public class BSTree<T extends  Comparable<T>> {
    /**
     *  根节点
     */
    private BstNode<T> mRoot;

    /**
     * 内部类
     * @param <T>
     */
    public class BstNode<T extends  Comparable<T>>{
        /**
         * 关键字
         */
        T key;
        /**
         * 左孩子
         */
        BstNode<T> left;
        /**
         * 右孩子
         */
        BstNode<T> right;
        /**
         * 父结点
         */
        BstNode<T> parent;

        public BstNode(T key, BstNode<T> left, BstNode<T> right,BstNode<T> parent){
            super();
            this.key = key;
            this.left = left;
            this.right = right;
            this.parent = parent;
        }
    }
}

插入:

先找到待插入的叶子结点,再在叶子结点上判断与key的关系,以判断key值应该插入到什么位置


    /**
     * 新建结点key,并将其插入到二叉树中
     * @param key  插入结点的键值
     */
    public void insert(T key){
        BstNode<T> z=new BstNode<T>(key, null, null, null);
        //如果新建结点失败,则返回
        if (z!=null) {
            insert(this,z);
        }
    }
    /**
     * 新建结点key,并将其插入到二叉树中
     * @param bst 二叉树
     * @param z 插入的结点
     */
    private void insert(BSTree<T> bst, BstNode<T> z) {
        int cmp;
        BstNode<T> y=null;
        BstNode<T> x=bst.mRoot;//x指向该树的根结点

        /**
         * 查找z的插入位置
         * 比较根结点x与新节点z之间的关系
         * 	这时,y结点指向根结点x,若z小于根结点,则x指向x的左子树;否则指向右子树
         * 	直到左/右子树为空  【y结点是x结点的父结点】
         * 此时,z.parent指向y

         * if y=null
         *	新节点z就是父结点;
         * else
         * 	比较z和y的大小,
         * 		if z<y
         * 			z插入到y的左孩子的位置
         * 		else
         * 			z插入到y的右孩子的位置
         */
        while(x!=null){
            y=x;
            cmp=z.key.compareTo(x.key);
            if (cmp<0) {
                x=x.left;
            }else {
                x=x.right;
            }
        }
        z.parent=y;
        if (y==null) {
            bst.mRoot=z;
        }else {
            cmp=z.key.compareTo(y.key);
            if (cmp<0) {
                y.left=z;
            }else {
                y.right=z;
            }
        }
    }
/**
 * @Description: 二叉查找树测试
 * @Author: llf
 * @CreateDate: 2019/12/14 16:29
 */
public class BSTreeTest {
    private static final int arr[] = {1, 5, 4, 3, 2, 6};

    public static void main(String[] args) {
        BSTree<Integer> tree = new BSTree<>();
        System.out.println("==依次添加:");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]+" ");
            tree.insert(arr[i]);
        }
    }
}

==依次添加:1 5 4 3 2 6

遍历:

  • 前序遍历 首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树,如果二叉树为空则返回。

输入图片说明

前序遍历==》ABDECF

若二叉树非空,则执行以下操作:

1、访问根节点

2、先序遍历左子树

3、先序遍历右子树

 /**
     * 前序遍历二叉树
     */
    public void preOrder(){
        preOrder(mRoot);
    }
    private void preOrder(BstNode<T> tree){
        if (tree!=null) {
            System.out.print(tree.key+" ");
            preOrder(tree.left);
            preOrder(tree.right);
        }
    }
 System.out.println("==前序遍历:");
  tree.preOrder();

==前序遍历:1 5 4 3 2 6

中序遍历 中序遍历首先遍历左子树,然后访问根结点,最后遍历右子树

输入图片说明

----》中序遍历结果:DBEAFC

若二叉树非空,则执行以下操作:

  1. 中序遍历左子

  2. 树访问根节点

  3. 中序遍历右子树

 /**
 * 中序遍历二叉树
 */
    public void inOrder(){
        inOrder(mRoot);
    }
    private void inOrder(BstNode<T> tree) {
        if (tree!=null) {
            inOrder(tree.left);
            System.out.print(tree.key+" ");
            inOrder(tree.right);
        }
    }

后序遍历 后序遍历首先遍历左子树,然后遍历右子树,最后访问根结点,在遍历左、右子树时,仍然先遍历左子树,然后遍历右子树,最后遍历根结点。

在这里插入图片描述

-----》后序遍历结果:DEBFCA

若二叉树非空,则执行以下操作:

1、后序遍历左子树

2、后序遍历右子树

3、访问根节点

 /**
     * 后序遍历二叉树
     */
    public void postOrder(){
        postOrder(mRoot);
    }
    private void postOrder(BstNode<T> tree) {
        if (tree!=null) {
            postOrder(tree.left);
            postOrder(tree.right);
            System.out.print(tree.key+" ");
        }
    }
   System.out.println("==后序遍历:");
   tree.postOrder();

==后序遍历:
2 3 4 6 5 1

什么是红黑树

二叉查找树BST——Java实现 https://blog.csdn.net/u014067137/article/details/80336127

猜你喜欢

转载自blog.csdn.net/fggsgnhz/article/details/103549019