二叉查找树的简单实现

原创 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版》

二叉搜索树的简单实现(Binary Search Tree)

一、二叉搜索树的概念 二叉搜索树,又称二叉排序树,二叉查找树,他能够高效的完成数据的插入,查询,删除操作,是一种高效的数据结构。 如下图就是一个构建好的二叉搜索树。 特点:    ...
  • chaiwenjun000
  • chaiwenjun000
  • 2015年09月18日 19:49
  • 1023

二叉查找树简单实现

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

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

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

二叉查找树的简单实现

虽然代码写了,部分还是参考教材,有的还不是很理解: #include #include struct TreeNode{ TreeNode(int aVal){ value = aVal...
  • boyhailong
  • boyhailong
  • 2014年01月16日 23:31
  • 749

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

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

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

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

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

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

二叉查找树的应用

二叉查找树又称为二叉排序树, 它或者是一棵空树;或者是具有下列性质的二叉树:      (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;      (2)若右子树不空,则右子树...
  • liuhuiyi
  • liuhuiyi
  • 2012年07月17日 14:34
  • 1055

数据结构-二叉树和二叉查找树

先按树-二叉树-二叉查找树的顺序解释会比较清楚。 一,树 树(Tree)是n(n≥0)个结点的有限集。在任意一棵非空树中: (1)有且仅有一个特定的被称为根(Root)的结点; (2)当n>1...
  • tuke_tuke
  • tuke_tuke
  • 2015年12月20日 17:44
  • 2153

二叉查找树的基本例程

使二叉树为二叉查找树(Binary Search Tree)的性质是:对于树中的每个节点X,它的左子树中所有关键字值小于X的关键字值,而它的右子树中所有关键字值大于X的关键字值。        ...
  • xiahouzuoxin
  • xiahouzuoxin
  • 2012年11月07日 20:13
  • 1868
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:二叉查找树的简单实现
举报原因:
原因补充:

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