偷懒方法

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. 【01】恶趣味玩转 GitHub commit 历史记录

    [黑科技]恶趣味玩转 GitHub commit 历史记录   工具:https://github.com/gelstudios/gitfiti 效果截图:预览地址:https://github.co ...

  2. 为应用指定多个struts配置文件

    在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿.为了避免struts.xml文件过于庞大.臃肿,提高struts.xml文件的可 ...

  3. Java并发编程:用AQS写一把可重入锁

    Java并发编程:自己动手写一把可重入锁详述了如何用synchronized同步的方式来实现一把可重入锁,今天我们来效仿ReentrantLock类用AQS来改写一下这把锁.要想使用AQS为我们服务, ...

  4. [POJ1797] Heavy Transportation(最大生成树 || 最短路变形)

    传送门 1.最大生成树 可以求出最大生成树,其中权值最小的边即为答案. 2.最短路 只需改变spfa里面的松弛操作就可以求出答案. ——代码 #include <queue> #inclu ...

  5. 【POJ3294】Life Forms(后缀数组,二分)

    题意: n<=100 len[i]<=1000 思路:这是一道论文题 ..]of longint; ch:..]of ansistring; n,n1,l,r,mid,last,i,j,m ...

  6. jQuery根据属性模糊匹配元素

    1.查看带有指定属性的元素: [attribute] 例如: $("div[id]") 2.查看属性值是某个特定值的元素: [attribute=value] 例如: $(&quo ...

  7. php 以单下划线或双下划线开头的命名

    有2个下划线的是魔术方法,如:__construct.__destruct等等.有1个下划线的一般是私有方法,如 _initialize. 小测试: public function _test(){ ...

  8. 如何通过AS3加载外部SWF文件,调用外部文件文档类的方法?

    一个Flash中通过AS3代码的Loader对象加载另一个SWF文件,并访问其中的文档类中的方法. 简单示例: 主文件:Main.fla, Main.as 被调用的文件:called.swf, Cal ...

  9. 时间戳转换成DateTime

    select DateAdd(hour,8,Dateadd(ss,时间戳,'1970-01-01'))   --1970/01/01+时间戳(秒数)+8小时 --因GMT是中央时区,北京在东8区,相差 ...

  10. S5700&S5710 产品文档 : 配置

    http://support.huawei.com/hdx/hdx.do?docid=SC0000699332&lang=zh&path=PBI1-C103367%2FPBI1-C10 ...