偷懒方法

public void delete(Key key) {
insert(key, null);
}

这样的方法就是将key相应的值覆盖成null。当读取该键值的时候将会返回null。

这是一种偷懒的办法,可是在严肃的实际应用中肯定不能这样,一方面会造成内存浪费,还有一方面性能会越来越慢。

正规方法

先从简单的问题開始吧,怎样删掉BST中最小的键呢?

先找到最小的键,然后将右子节点挂在父节点上。

代码:

public void deleteMin() {
root = deleteMin(root);
} private Node deleteMin(Node node) {
if(node.left != null) {
node.left = deleteMin(node.left);
node.count -= 1;
return node;
} else {
return node.right;
}
}

删除随意节点

删除随意节点的时候有三种情况能够考虑:

  • 删除一个没有子节点的节点很easy了,仅仅要返回null就可以

  • 删除一个仅仅有一个子节点的节点须要返回它唯一的一个子节点

  • 最难的问题在于删除一个有两个子节点的节点。这时候就要将右子树中最小的节点分离出来。放在该节点原本的位置。这就是Hibbard删除法。

可是Hibbard删除法在使用一段时间后发现。整个树变得越来越不平衡。因此Hibbard删除法的平均复杂度是sqrtN。有人提出删除的时候随机取出左側或右側的继承节点。

代码:

public void delete(Key key) {
root = delete(root, key);
} private Node delete(Node node, Key key) {
// 先定位到须要删除的点
if(node == null) return null;
int compare = key.compareTo(node.key);
if(compare < 0) {
node.left = delete(node.left, key);
updateCount(node);
return node;
} else if(compare > 0) {
node.right = delete(node.right, key);
updateCount(node);
return node;
} // 已定位到相应的节点,開始删除。下面是没有子节点或仅仅有1个子节点的情况
if(node.left == null) return node.right;
if(node.right == null) return node.left; // 有两个子节点时,採用Hibbard删除法,取出右側最小的节点代替被删除的节点
Node minNode = minNode(node.right);
node.right = deleteMin(node.right);
minNode.left = node.left;
minNode.right = node.right;
updateCount(minNode);
return minNode;
} private void updateCount(Node node) {
node.count = 1+size(node.left)+size(node.right);
} private Node minNode(Node root) {
if(root == null) return null; Node node = root;
while(node.left != null) {
node = node.left;
}
return node;
}

兴许章节将会介绍红黑树,它能保证全部的操作都能保证logN复杂度。

算法4-10:BST平衡二叉树的删除操作的更多相关文章

  1. 平衡二叉树算法实现 c语言版 插入 删除

    #include <stdio.h>#include <malloc.h>#include<stdlib.h> #define EQ(a,b) ((a)==(b)) ...

  2. 算法与数据结构(十一) 平衡二叉树(AVL树)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  3. 算法与数据结构(十一) 平衡二叉树(AVL树)(Swift版)

    今天的博客是在上一篇博客的基础上进行的延伸.上一篇博客我们主要聊了二叉排序树,详情请戳<二叉排序树的查找.插入与删除>.本篇博客我们就在二叉排序树的基础上来聊聊平衡二叉树,也叫AVL树,A ...

  4. MyBatis知多少(22)MyBatis删除操作

    本节从表中使用MyBatis删除记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT NOT NULL auto_increment, f ...

  5. ***Redis hash是一个string类型的field和value的映射表.它的添加、删除操作都是O(1)(平均)。hash特别适合用于存储对象

    http://redis.readthedocs.org/en/latest/hash/hset.html HSET HSET key field value   (存一个对象的时候key存) 将哈希 ...

  6. Java创建二叉搜索树,实现搜索,插入,删除操作

    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...

  7. Java中list如何利用遍历进行删除操作

    转: Java中list如何利用遍历进行删除操作 2018年03月31日 10:23:41 Little White_007 阅读数:3874   Java三种遍历如何进行list的便利删除: 1.f ...

  8. Golang map 如何进行删除操作?

    Cyeam 关注 2017.11.02 10:02* 字数 372 阅读 2784评论 0喜欢 3 map 的删除操作 Golang 内置了哈希表,总体上是使用哈希链表实现的,如果出现哈希冲突,就把冲 ...

  9. ADO.NET 使用DELETE语句批量删除操作,提示超时,删除失败,几种优化解决思路

    起因是如此简单的一句sql 提示:Timeout 时间已到.在操作完成之前超时时间已过或服务器未响应. 提供几种解决思路: 1.检查WHERE条件中字段是否已建索引 2.检查是否被其他表引用,引用表外 ...

随机推荐

  1. LeetCode(77) Combinations

    题目 Given two integers n and k, return all possible combinations of k numbers out of 1 - n. For examp ...

  2. Android记录2013年10月20日

    1. ailed to fectch URl https://dl-ssl.google.com/android/repository/addons_list.xml, reason: Connect ...

  3. javaweb 开发所需工具和入门教程文档等

    下载网址 1.JDK1.8下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...

  4. BeautifulSoup实例

    Beautiful Soup 4.4.0 中文文档:http://beautifulsoup.readthedocs.io/zh_CN/latest/ #coding:utf-8from bs4 im ...

  5. hihoCoder#1127 二分图三·二分图最小点覆盖和最大独立集

    原题地址 主要是介绍了两个定理: 1. 二分图最大匹配数    = 二分图最小点覆盖数 2. 二分图最小点覆盖数 = 二分图顶点数 - 二分图最小点覆盖数 注意,都是二分图 代码:(匈牙利算法) #i ...

  6. iOS时钟,秒针扫秒样式

    昨天做一个时钟小demo,发现了一些问题. 描述能力有限,我封装好了一个时钟框架,朋友们可以参考      https://github.com/qianlishun/ClockView 点击这里可以 ...

  7. 路线统计(codevs 1482)

    题目描述 Description N个节点的有向图, 求从start到finish刚好经过时间time的总方案数 mod 502630. 输入描述 Input Description 第一行包含一个整 ...

  8. linux日志服务器审计客户端history记录

    https://blog.csdn.net/yanggd1987/article/details/70255179

  9. 洛谷——P2068 统计和

    P2068 统计和 题目描述 给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=1000 ...

  10. 学习日常笔记<day16>mysql加强

    1.数据约束 1.1什么是数据约束 对用户操作表的数据进行约束 1.2 默认值 作用:当永辉对使用默认值的字段不插入值的时候,就使用默认值 注意: 1)对默认值字段插入null是可以的 2)对默认值字 ...