二叉搜索树

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
具体介绍和实现:https://blog.csdn.net/hebtu666/article/details/81741034

我们知道,对于一般的二叉搜索树(Binary Search Tree),其期望高度(即为一棵平衡树时)为log2n,其各操作的时间复杂度(O(log2n))同时也由此而决定。但是,在某些极端的情况下(如在插入的序列是有序的时),二叉搜索树将退化成近似链或链,

此时,其操作的时间复杂度将退化成线性的,即O(n)。我们可以通过随机化建立二叉搜索树来尽量的避免这种情况,但是在进行了多次的操作之后,由于在删除时,我们总是选择将待删除节点的后继代替它本身,这样就会造成总是右边的节点数目减少,以至于树向左偏沉。这同时也会造成树的平衡性受到破坏,提高它的操作的时间复杂度。

概念引入

Abstract Self-Balancing Binary Search Tree:自平衡二叉搜索树

顾名思义:它在面对任意节点插入和删除时自动保持其高度

常用算法有红黑树、AVL、Treap、伸展树、SB树等。在平衡二叉搜索树中,我们可以看到,其高度一般都良好地维持在O(log(n)),大大降低了操作的时间复杂度。这些结构为可变有序列表提供了有效的实现,并且可以用于其他抽象数据结构,例如关联数组,优先级队列和集合。

对于这些结构,他们都有自己的平衡性,比如:

AVL树

具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

根据定义可知,这是根据深度最严苛的标准了,左右子树高度不能差的超过1.

具体介绍和实现:https://blog.csdn.net/hebtu666/article/details/85047648

红黑树

特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

根据定义,确保没有一条路径会比其他路径长出2倍。

size balance tree

Size Balanced Tree(简称SBT)是一自平衡二叉查找树,是在计算机科学中用到的一种数据结构。它是由中国广东中山纪念中学的陈启峰发明的。陈启峰于2006年底完成论文《Size Balanced Tree》,并在2007年的全国青少年信息学奥林匹克竞赛冬令营中发表。由于SBT的拼写很容易找到中文谐音,它常被中国的信息学竞赛选手和ACM/ICPC选手们戏称为“傻B树”、“Super BT”等。相比红黑树、AVL树等自平衡二叉查找树,SBT更易于实现。据陈启峰在论文中称,SBT是“目前为止速度最快的高级二叉搜索树”。SBT能在O(log n)的时间内完成所有二叉搜索树(BST)的相关操作,而与普通二叉搜索树相比,SBT仅仅加入了简洁的核心操作Maintain。由于SBT赖以保持平衡的是size域而不是其他“无用”的域,它可以很方便地实现动态顺序统计中的select和rank操作。

对于SBT的每一个结点 t,有如下性质:
   性质(a) s[ right[t] ]≥s[ left [ left[ t ] ] ], s[ right [ left[t] ] ]
   性质(b) s[ left[t] ]≥s[right[ right[t] ] ], s[ left[ right[t] ] ]
即.每棵子树的大小不小于其兄弟的子树大小。

伸展树

伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入、查找和删除操作。它由Daniel Sleator和Robert Tarjan创造。它的优势在于不需要记录用于平衡树的冗余信息。在伸展树上的一般操作都基于伸展操作。

Treap

Treap是一棵二叉排序树,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是,Treap纪录一个额外的数据,就是优先级。Treap在以关键码构成二叉排序树的同时,还满足堆的性质(在这里我们假设节点的优先级大于该节点的孩子的优先级)。但是这里要注意的是Treap和二叉堆有一点不同,就是二叉堆必须是完全二叉树,而Treap并不一定是。

对比可以发现,AVL树对平衡性的要求比较严苛,每插入一个节点就很大概率面临调整。

而红黑树对平衡性的要求没有那么严苛。可能是多次插入攒够了一下调整。。。

把每一个树的细节都扣清楚是一件挺无聊的事。。虽然据说红黑树都成了面试必问内容,但是实在是不想深究那些细节,这些树的基本操作也无非是那么两种:左旋,右旋。这些树的所有操作和情况,都是这两种动作的组合罢了。

所以本文先介绍这两种基本操作,等以后有时间(可能到找工作时),再把红黑树等结构的细节补上。

最简单的旋转

最简单的例子:

这棵树,左子树深度为2,右子树深度为0,所以,根据AVL树或者红黑树的标准,它都不平衡。。

那怎么办?转过来:

是不是就平衡了?

这就是我们的顺时针旋转,又叫,右旋,因为是以2为轴,把1转下来了。

左旋同理。

带子树旋转

问题是,真正转起来可没有这么简单:

这才是一颗搜索树的样子啊

ABCD都代表是一颗子树。我们这三个点转了可不能不管这些子树啊对不对。

好,我们想想这些子树怎么办。

首先,AB子树没有关系,放在原地即可。

D作为3的右子树,也可以不动,那剩下一个位置,会不会就是放C子树呢?

我们想想能否这样做。

原来:

1)C作为2的右子树,内任何元素都比2大。

2)C作为3左子树的一部分,内任何元素都比3小。

转之后:

1)C作为2的右子树的一部分,内任何元素都比2大。

2)C作为3左子树,内任何元素都比3小。

所以,C子树可以作为3的左子树,没有问题。

这样,我们的操作就介绍完了。

这种基本的变换达到了看似把树变的平衡的效果。

左右旋转类似

代码实现

对于Abstract BinarySearchTree类,上面网址已经给出了思路和c++代码实现,把java再贴出来也挺无趣的,所以希望大家能自己实现。

抽象自平衡二叉搜索树(AbstractSelfBalancingBinarySearchTree)的所有操作都是建立在二叉搜索树(BinarySearchTree )操作的基础上来进行的。

各种自平衡二叉搜索树(AVL、红黑树等)的操作也是由Abstract自平衡二叉搜索树的基本操作:左旋、右旋构成。这个文章只写了左旋右旋基本操作,供以后各种selfBalancingBinarySearchTree使用。

public abstract class AbstractSelfBalancingBinarySearchTree extends AbstractBinarySearchTree {protected Node rotateRight(Node node) {Node temp = node.left;//节点2temp.parent = node.parent;//节点3的父(旋转后节点2的父)node.left = temp.right;//节点3接收节点2的右子树if (node.left != null) {node.left.parent = node;}temp.right = node;//节点3变为节点2的右孩子node.parent = temp;//原来节点3的父(若存在),孩子变为节点2if (temp.parent != null) {if (node == temp.parent.left) {temp.parent.left = temp;} else {temp.parent.right = temp;}} else {root = temp;}return temp;}protected Node rotateLeft(Node node) {Node temp = node.right;temp.parent = node.parent;node.right = temp.left;if (node.right != null) {node.right.parent = node;}temp.left = node;node.parent = temp;if (temp.parent != null) {if (node == temp.parent.left) {temp.parent.left = temp;} else {temp.parent.right = temp;}} else {root = temp;}return temp;}
}

Abstract Self-Balancing Binary Search Tree相关推荐

  1. 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)

    议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...

  2. 【ACM】二叉搜索树(Binary Search Tree /BS Tree) 小结

    动态管理集合的数据结构--二叉搜索树 搜索树是一种可以进行插入,搜索,删除等操作的数据结构,可以用字典或者优先队列. 二叉排序树又称为二叉查找树,他或者为空树,或者是满足如下性质的二叉树. (1)若它 ...

  3. 二叉搜索树(binary search tree)的建立、删除、查找

    由于输入的数据顺序不同,建立的bst会不一样.最坏的情况就是一个链,所以我们引入了平衡二叉树的概念.这里我们先来看binary search tree.(我随笔里面有一些相关知识) 建立(也就是插入) ...

  4. 查找二叉树中出现次数最多的数 Find Mode in Binary Search Tree

    为什么80%的码农都做不了架构师?>>>    问题: Given a binary search tree (BST) with duplicates, find all the  ...

  5. LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List--转换二叉树为双向链表--Java,C++,Python解法

    题目地址:Convert Binary Search Tree to Sorted Doubly Linked List - LeetCode Convert a BST to a sorted ci ...

  6. LeetCode: 109. Convert Sorted List to Binary Search Tree

    题目 Given a singly linked list where elements are sorted in ascending order, convert it to a height b ...

  7. 学习数据结构 二叉查找树(binary search tree)

    2019独角兽企业重金招聘Python工程师标准>>> 为学习 LLVM 的 ImmutableSet,其底层的实现选择为 AVL 树(平衡二叉搜索树),我不很熟悉该树,虽然大致知道 ...

  8. Recover Binary Search Tree

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  9. Lowest Common Ancestor of a Binary Search Tree(树中两个结点的最低公共祖先)

    题目描述: Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in ...

最新文章

  1. u8 采购到货单中的 业务类型 没有表字典,是系统预置 存入表也是文字: 普通采购 - 固定资产...
  2. wust 1599弗洛伊德
  3. 讯wifi_罗永浩直播带货,网友为何pick讯飞智能录音笔?
  4. 关于近期对Lucene.Net应用研究学习的总结
  5. JAVA并发编程学习笔记------FutureTask
  6. Python高阶函数用法
  7. java程序算法实例_java编程算法经典案例
  8. ubuntu系统下VirtualBox安装windows虚拟机
  9. 查找恶意的TOR中继节点
  10. gnu/stubs-32.h
  11. iOS-instrument使用
  12. python非法的标识符_Python标识符
  13. Unity内置Shader解读2——Bumped Specular
  14. 关系型数据库由哪三部分组成_关系数据库| 第2部分
  15. C# 获取Windows系统ICON图标的四种方式-可提取各种文件夹、文件等等图标
  16. xcode 可以打开xmind_XMind 推出的轻量化脑图工具,时隔两年迎来大版本更新:Lighten 2...
  17. .Net混淆工具和反混淆工具
  18. Linux安装mql
  19. valgrind tool suite
  20. 大数据毕业设计 协同过滤商品推荐系统设计与实现

热门文章

  1. python文本风格_以写代学:python 良好的代码风格实例解析
  2. java 并列排名,178. 分数排名
  3. openssl-1.0.0b - libssl 移植到ARM Linux
  4. cmake 学习笔记(一)
  5. PJSIP学习笔记——PJSUA层发起呼叫的主要流程
  6. qt 添加依赖库lib_在QT中添加LIB的方法
  7. efishell无法开机shell_开机出现efi shell卡住不动了解决方法全集
  8. 【转】matlab函数编译成dll供Cpp调用的方法
  9. 【转】刨根究底字符编码【2.0版】(1):开篇
  10. .NET 实现并行的几种方式(三)