BST --- Java版

一. 简介

二叉查找树(BST)是二叉树的一个重要的应用,它在二叉树的基础上加上了这样的一个性质:对于树中的每一个节点来说,如果有左儿子的话,它的左儿子的值一定小于它本身的值,如果有右儿子的话,它的右儿子的值一定大于它本身的值。
  我用一句话概括:左 < 中 < 右。 根据这个原理,我们可以推断:BST的中序遍历必定是严格递增的

二. 数据结构

public class BST<T extends Comparable<T>> {
    class Node {
        private T data;
        private Node left;
        private Node right;
        private int N;

        public Node(T data, int N) {
            this.data = data;
            this.N = N;
            this.left = null;
            this.right = null;
        }
    }

    private Node root;

    public int size() {
        return size(root);
    }

    private int size(Node n) {
        if (n == null) return 0;
        else return n.N;
    }

    public void put(T x) {
        root = put(root, x);
    }

    public Node min() {
        return min(root);
    }

    private Node min(Node n) {
        if (n == null)
            return null;
        while (n.left != null) {
            n = n.left;
        }
        return n;
    }

    private Node put(Node n, T x) {
        if (n == null) return new Node(x, 1);  //树为空
        int cmp = x.compareTo(n.data);
        if (cmp < 0) {
            n.left = put(n.left, x);
        } else if (cmp > 0) {
            n.right = put(n.right, x);
        } else n.data = x;
        n.N = 1 + size(n.left) + size(n.right);
        return n;
    }

    public void delete(T x) {
        if (x == null) throw new IllegalArgumentException("called delete() with a null key");
        root = delete(root, x);
    }

    private Node delete(Node n, T x) {
        if (n == null) return null;
        int cmp = x.compareTo(n.data);
        if (cmp < 0) {
            n.left = delete(n.left, x);
        } else if (cmp > 0) {

        } else {  //如果相等,此节点就是要删除的节点
            if (n.left == null)
                return n.right;     // 这里return,相当于把当前节点的直接右节点连到当前节点的父节点
            if (n.right == null)
                return n.left;      // 这里return,相当于把当前节点的直接左节点连到当前节点的父节点
            // 有2个孩子
            Node t = n;
            n = min(t.right);       // t的右子树最小的节点替换这个被删除的节点
            n.right = deleteMin(t.right);
            n.left = t.left;
        }
        n.N = size(n.left) + size(n.right) + 1;
        return n;
    }

    private Node deleteMin(Node n) {
        if (n.left == null) return n.right;
        n.left = deleteMin(n.left);
        n.N = size(n.left) + size(n.right) + 1;
        return n;
    }
}

  1. 插入:
      根据二叉查找树的性质,插入一个节点的时候,如果根节点为空,就此节点作为根节点,如果根节点不为空,就要先和根节点比较,如果比根节点的值小,就插入到根节点的左子树中,如果比根节点的值大就插入到根节点的右子树中,如此递归下去,找到插入的位置。重复节点用新值更新。如图1是一个插入的过程。
图1.png
  1. 查找:
      查找的功能和插入差不多一样,按照插入那样的方式递归下去,如果找到了,就返回这个节点的地址,如果没有找到,就返回null。

3.删除:
  1⃣️ 首先先实现删除这个树中最小的元素: Node deleteMin(Node n){}函数.
思路是:

  • 一直找节点Node的左子树,直到找到当前节点的左儿子为空(n.left == null,)
  • 用找到的这个节点n的右儿子来替代它自己,这个节点n会没有引用被gc掉
  • 更新节点数目
图2.png

2⃣️ 然后删除某个节点:
  如果是叶子节点的话,直接删除就可以了。比如图3,要删除的是C节点,它是叶子节点,那么很简单把它父节点的引用置为null。

图3.png

  如果只有一个孩子的话,就让它的父亲指向它的儿子,然后删除这个节点。如下图:

图4.png

删除有两个儿子的节点会比较复杂一些。一般的删除策略是用其右子树最小的数据代替该节点的数据并递归的删除掉右子树中最小数据的节点。因为右子树中数据最小的节点肯定没有左儿子,所以删除的时候容易一些。(比如删除下图的E节点,那么会找到E节点右子树中最小的节点来替代节点E,如图是H节点, 当H代替完E节点,接下来调用deleteMin(E节点)删除H节点)

图5.png

三. 复杂度

平均复杂度 最坏情况复杂度

  • 插入操作 O(logN)   O(N)

  • 查询操作 O(logN)   O(N)

  • 删除操作 O(logN)   O(N)

如果BST不是平衡的树,如下图退化成list,那么最大复杂度O(N)。如插入有序序列(1, 2, 3, 4, 5),插入操作完成后的BST如下图:

图6.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 红黑树是平衡二叉查找树的一种。为了深入理解红黑树,我们需要从二叉查找树开始讲起。 BST 二叉查找树(Binary...
    kanehe阅读 1,370评论 0 8
  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 4,442评论 1 31
  • 以前喜欢把自己的思绪倾泄于笔端,觉得这是一种放松自己心情的好的方式。但是近来却越发没有这种心思了,更多的时候是心情...
    小城幽篁阅读 267评论 0 0
  • 你讨厌爸爸,没有责任感,自私,短视,懦弱自卑,还喜欢大男子主义…… 你讨厌下属,不只知,自大无脑,离谱,消极,……...
    吾空空阅读 203评论 0 0
  • 我也不知道要写什么。先写起来。只是笃信写作的重要,所以打起键盘写了。还有个原因,我的一个微信群要求周二主题讨论,我...
    wendy_zo阅读 147评论 0 0