二叉查找树的简单实现

原创 2017年07月07日 10:55:37

二叉查找树首先也是个二叉树,符合二叉树的一切特点。

原文地址:http://blog.csdn.net/qq_25806863/article/details/74638590

简单介绍

但是二叉查找树要求对树中的每个节点,这个节点的左子树中所有的值要小于自己,右子树中所有的值要大于自己。

下面是两个的区别:

二叉查找树:
这里写图片描述

不是二叉查找树:
这里写图片描述

简单实现

主要是查询,插入和删除的方法

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

    private BinaryNode<E> root;

    public MySearchTree() {
        root = null;
    }

    public void makeEmpty() {
        root = null;
    }

    public boolean isEmpty() {
        return root == null;
    }

    public boolean contains(E x) {
        return contains(x, root);
    }

    public E findMin() {
        return findMin(root).element;
    }

    public E findMax() {
        return findMax(root).element;
    }

    public void insert(E x) {
        root =  insert(x, root);
    }

    public void remove(E x) {
        remove(x, root);
    }

    public void printTree() {
        printTree(root);
    }


    /**
     * 如果这个树上的值就是要查找的x,返回true
     * 如果树为空,说明不存在这个值,返回false
     * 如果x小于这个树上的值,就在这个树的左子树上递归查找
     * 如果x大于这个树上的值,就在这个树的右子树上递归查找
     */
    private boolean contains(E x, BinaryNode<E> tree) {
        if (tree == null) {
            return false;
        }
        int compareResult = x.compareTo(tree.element);
        if (compareResult < 0) {
            return contains(x, tree.left);
        } else if (compareResult > 0) {
            return contains(x, tree.right);
        } else {
            return true;
        }
    }


    /**
     * 只要有左子树就一直往左找,左子树为空说明这个就是最小值
     */
    private BinaryNode<E> findMin(BinaryNode<E> tree) {
        if (tree == null) {
            return null;
        } else if (tree.left == null) {
            return tree;
        } else {
            return findMin(tree.left);
        }

    }

    /**
     * 只要有右子树就一直往左找,右子树为空说明这个就是最大值
     */
    private BinaryNode<E> findMax(BinaryNode<E> tree) {
        if (tree == null) {
            return null;
        } else if (tree.right == null) {
            return tree;
        } else {
            return findMax(tree.right);
        }
    }

    /**
     * 如果要插入的树是null,说明这个就是要插入的值该放的位置,new一个子树,绑定到对应的父亲上
     * 如果树不为null,说明这个树上有值,拿x和这个值进行比较
     * 如果两个值相等,说明已经有这个值了,可以进行一些处理
     * 如果x小于树上的值,就往该树的左子树上递归插入
     * 如果x大于树上的值,就往该树的右子树上递归插入
     */
    private BinaryNode<E> insert(E x, BinaryNode<E> tree) {
        if (tree == null) {
            return new BinaryNode<E>(x, null, null);
        }
        int compareResult = x.compareTo(tree.element);
        if (compareResult < 0) {
            tree.left= insert(x, tree.left);
        } else if (compareResult > 0) {
            tree.right =  insert(x, tree.right);
        } else {
            //说明已经有这个值了。
            System.out.println("已经有这个值了");
        }
        return tree;
    }


    /**
     * 比较x和树的值
     * 如果x小于树的值,在树的左子树中递归删除
     * 如果x大于树的值,在树的右子树中递归删除
     * 如果x等于树的值,那么这个值就是要删除的值。
     * 因为删除一个值就要对树进行重新排列,所以这个位置上不能空。
     * 如果这个树只有一个子树,那么就直接把这个子树放在这个位置上
     * 如果这个树有两个子树,那么需要找到右子树的最小值,将这个最小值赋值在要删除的位置上,
     * 然后递归调用从右子树中删除刚刚找到的这个最小值
     */
    private BinaryNode<E> remove(E x, BinaryNode<E> tree) {
        if (tree == null) {
            //没有这个树
            return tree;
        }
        int compareResult = x.compareTo(tree.element);
        if (compareResult < 0) {
            tree.left = remove(x, tree.left);
        } else if (compareResult > 0) {
            tree.right = remove(x, tree.right);
        } else if (tree.left != null && tree.right != null) {
            tree.element = findMin(tree.right).element;
            tree.right = remove(tree.element, tree.right);
        } else {
            tree = (tree.left != null) ? tree.left : tree.right;
        }
        return tree;

    }

    private void printTree(BinaryNode<E> tree) {
        if (tree == null) {
            return;
        }
        System.out.print(tree.element+" ");
        printTree(tree.left);
        printTree(tree.right);

    }

    public static class BinaryNode<E> {
        E element;
        BinaryNode<E> left;
        BinaryNode<E> right;

        public BinaryNode(E element) {
            this(element, null, null);
        }

        public BinaryNode(E element, BinaryNode<E> left, BinaryNode<E> right) {
            this.element = element;
            this.left = left;
            this.right = right;
        }
    }
}

实现的缺点

在代码中,注意remove方法中的一段代码:

else if (tree.left != null && tree.right != null) {
    tree.element = findMin(tree.right).element;
    tree.right = remove(tree.element, tree.right);

这里对删除的处理是,找到右子树中的最小值,把这个最小值放在当前节点上,然后从右子树中删除这个值。

而在insert的时候,是根据比较而随机的插入在左右子树上的。

所以如果交叉调用insert和remove很多次的话,这个二叉树会变得很不平衡,即左右子树的高度差很大。

这种平衡的二叉查找树叫平衡查找树

一个最古老的平衡查找树是AVL树

参考《数据结构与算法分析java版》

二叉查找树简单实现

二叉查找树其实在实际中起效率非常高,特别在于处理其中的数据。实际工作中我认为会有用处的: 1、中序排列是一个按照从到大的序列来实现的; 2、删除一个元素,会在右子树的最小的一个元素来进行补上其位置...
  • qq_33405276
  • qq_33405276
  • 2017-09-11 22:53:01
  • 72

二叉查找树的简单实现(C语言版)

老司机不多说,直接上代码 头文件:#ifndef BINARYTREE_FIND_H_INCLUDED #define BINARYTREE_FIND_H_INCLUDEDstruct TreeNo...
  • xiaodu1997
  • xiaodu1997
  • 2016-11-06 16:49:32
  • 940

java 数据结构 二叉查找树的简单实现

什么是二叉查找树二叉查找树是一种树结构。首先是二叉树。它表示每个节点最多有两个子节点,而二叉查找树,它还要求左子节点必须比右子节点小。 对于这个结构,我们以下几个操作的实现:树中的元素必须能比较这里...
  • lqx_sunhan
  • lqx_sunhan
  • 2018-01-16 17:50:24
  • 14

一颗二叉查找树的简单实现

第一次实现的二叉查找树,在别的大牛的博客学习了很久很久。发现由于其使用的技巧较多,不适用与新手模仿,所以自己实践写出了一个有局限性,功能专一化,不完整的二叉查找树。        使用了c++中的类来...
  • qq_37957829
  • qq_37957829
  • 2017-03-20 12:09:08
  • 131

[数据结构]二叉查找树 简单实现

/* Name:二叉查找树 简单实现 Actor:HT Time:2015年10月11日 Error Reporte: 1.子函数中给指针赋予新的地址的时候,不要忘记引用... 2.找...
  • z354681250
  • z354681250
  • 2015-10-11 00:13:39
  • 210

二叉查找树的插入和删除简单实现

插入代码: void InsertOfBSTree(BiSTree * pHeadNode,int ToBeInsertedNum) { BiSTree * pNode=pHea...
  • hongliyin
  • hongliyin
  • 2013-04-18 22:30:41
  • 427

Java二叉查找树最简单实现

什么是二叉树 简单来说,二叉树首先是一棵树,然后有以下条件 每个节点最多有2个孩子节点 二叉树有 一个根节点 一个左子树(可能为空) 一个右子树(可能为空) 特例 完全二叉树 叶...
  • yjw123456
  • yjw123456
  • 2018-04-12 17:30:31
  • 32

LintCode 85-在二叉查找树中插入节点

本人电子系,只为一学生。心喜计算机,小编以怡情。给定一棵二叉查找树和一个新的树节点,将节点插入到树中。你需要保证该树仍然是一棵二叉查找树。 思路:从最顶层一次次比较,最后落在想要插入的节点上。 ...
  • Jason__Liang
  • Jason__Liang
  • 2017-01-04 18:12:30
  • 309

二叉查找树的典型面试题目汇总

二叉查找树的经典面试题
  • huruzun
  • huruzun
  • 2014-03-22 15:34:13
  • 1174

【BZOJ1564】[NOI2009]二叉查找树【区间DP】

【题目链接】 这是一棵Treap,而且我们知道BST的中序遍历的数据值是递增的,那么我们按照数据值排个序,就得到中序遍历了。然后就变成区间DP啦。 设dp[l][r][m]表示,区间[l, r]的...
  • BraketBN
  • BraketBN
  • 2016-04-26 15:21:18
  • 455
收藏助手
不良信息举报
您举报文章:二叉查找树的简单实现
举报原因:
原因补充:

(最多只允许输入30个字)