精华内容
下载资源
问答
  • 红黑树

    2019-07-21 18:38:00
    一、红黑树缺点 1.1、数据量大,树高度会很高导致查找速度慢 转载于:https://www.cnblogs.com/chenweichu/p/11222167.html

    一、红黑树缺点

    1.1、数据量大,树高度会很高导致查找速度慢

    转载于:https://www.cnblogs.com/chenweichu/p/11222167.html

    展开全文
  • 红黑树已经有很长的历史,在许多现代编程语言的符号表中都有使用,但是其缺点也很明显,其代码实现过于繁杂。因此出现的红黑树的修改版——左倾红黑树 左倾红黑树的代码实现相比于典型的红黑树来说非常简介,但是...

    红黑树已经有很长的历史,在许多现代编程语言的符号表中都有使用,但是其缺点也很明显,其代码实现过于繁杂。因此出现的红黑树的修改版——左倾红黑树

    左倾红黑树的代码实现相比于典型的红黑树来说要简单不少,但是国内论坛好像并没有一个对于左倾红黑树相对系统的介绍,因此我找到了左倾红黑树的论文并将其整理翻译,以供学习

    由于过于繁杂,因此翻译的时候未对性能分析部分进行翻译,在这里提供原文地址

    在阅读本文前读者需要详细的了解二叉搜索树(BST)、红黑树、2-3树及2-3-4树

    由于能力有限,因此翻译的时候难免有不准确的地方,这个翻译仅供学习参考

    论文地址:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.139.282

    左倾红黑树
    罗伯特塞奇威克
    计算机科学系
    普林斯顿大学
    普林斯顿,新泽西州08544

    简介

    在用于实现平衡搜索的红黑树模型现在遍布我们的计算基础设施,在许多标准教科书中都有对红黑树的描述,是C++,Java,Python,BSD Unix等许多现代系统中符号表实现的基础数据结构。但是,其中许多实现牺牲了一些原始设计目标,因此设计一种新的模式是有价值的。

    在这篇论文中,描述了一种新的红黑树变体,它满足了许多原始设计目标,并且导致插入/删除的代码简单的多,仅需要常用实现代码的四分之一。

    所有红黑树都是基于2-3树或2-3-4树的变种,使用红色链接绑定到三节点或四节点。新代码基于三个概念的组合:

    1:使用递归实现

    2:要求所有三节点向左倾斜

    3:在树的上面执行旋转(在执行递归之后)

    这些想法不仅能生成简单的代码,而且还能统一算法:例如在2-3树的左倾版本和2-3-4树中的自顶向下的版本在一行代码的位置不同

    具体来说,在由一个N个键构成的左倾红黑2-3树种,一个搜索操作需要检查lgN - 0.5个节点,树的平均高度约为2ln n

    在LLBR(左倾红黑树)中由许多吸引人的特性:

    1:实验研究未能将这些算法与最优算法区分开

    2:它可以通过向标准BST(二叉搜索树)算法添加几行代码来实现。

    3:与散列表不同,他们支持有序操作,如:SELECT,RANK,RANGE搜索

    因此LLRB树对于各种符号表应用程序都很有用,并且是未来软件库中作为符号表基础的主要候选对象

    介绍

    我们在本文中关注的是包含通用键和关联值得符号表中提供以下操作的有效实现的目标:

    1:搜索/获取与给定键关联的值

    2:将键值对插入符号表中

    3:使用符号表中给定的键删除键值对

    4:当插入操作涉及表中已有的键时,我们将该键与指定的新值关联,因此表中没有重复的键

    我们进一步假设键是可比较的:我们有一个比较操作可以确定一个给定的键是否小于,等于,或大于另一个给定的键,这样我们就可以保留实现有序关联数组的能力,我们可以支持搜索、范围搜索和类似的操作。

    红黑树最重要的特征之一是他们不会增加搜索的开销,这是最常用的操作。因此,红黑树是C++,Java,Python,BSD Unix和许多其他系统中符号表实现的基础数据结构,为什么要重新审视这样一个成功的数据结构?在实现红黑树的时候,实际的代码很难维护并在新系统中重用,因为它很长,在典型的实现代码有100 - 200行代码,教科书中很少有完整实现。在本文中,我们提出了一种可以大大减少所需代码量的方法。为了证明这一点,我们提出一个完整的Java实现,包括三个简短使用的方法,为标准BST代码添加3行代码以进行插入,使用5行代码删除最大值,以及额外30行删除代码

    旋转和颜色翻转

    观察红黑树算法的一种方法是在插入和删除操作下维护以下不变的属性:

    1:从跟到低的路径不包含两个连续的红色链接

    2:每个路径上黑色链接的数量是相同的

    这些不变量限制了有N个节点的红黑树每条路径长度不会2lgn,这种最糟糕的情况发生在一个节点都是黑色的树中

    平衡树算法用于在插入和删除下保持平衡的基本操作称为旋转。

    在红黑树的前提下,这些操作很容易理解为将红色链接向左倾斜的3节点转换为向右倾斜和反向倾斜的3节点所需的转换

    旋转操作显然保留了上述两个不变量,在红黑树中,我们还使用一种称为颜色翻转(color flip)的简单操作。就2-3-4树而言,颜色翻转是必不可少的操作:它对应于分割4节点并将中间节点传递给父节点,颜色翻转显然不会改变从跟到底的任何路径上黑色链接的数量,但是它可能在树中引入两

    个连续的红色链接,必须进行更正

    红黑树算法在是否以及何时进行旋转和颜色翻转方面存在差异,以便维护上面的不变量

    左旋(Left rotate)

    在这里插入图片描述

    右旋(Right rotate)

    在这里插入图片描述

    颜色翻转

    在这里插入图片描述

    该串代码将节点h及h的两个孩子颜色翻转,变为与之前相反的颜色。具体的Node类型会在后面阐述

    左倾红黑树

    代码的起点是标准BST的Java实现,如下面的代码所示。在下面的代码中使用泛型以一种类型安全的方式实现,如果不使用泛型则代码是标准的,可以轻松的翻译成其他语言或应用于不需要泛型类型的特定应用程序。

    在目前的上下文中,实现的一个重要特性是insert()的实现是递归的:每个递归都以一个链接(link)作为参数并返回一个链接,该链接用于重置从该链接获取的字段(这么说很抽象,原文大概原意就是每次递归获得一个新的节点,用这个新的节点再次进行递归)。对于标准的BST,除了树的底部,参数和返回值是相同的。这里的代码(insert())用于插入新节点。对于红黑树,这个递归有助于简化代码

    除此之外,对于search()操作也可以使用递归实现。但是这里并不会使用递归实现,因为这个操作属于典型的程序内部循环,实现红黑树算法的基础实在这段代码中添加旋转和颜色翻转操作。以便维护树中的平衡不变量

    在本文的代码中,我们展示了可以通过以下方式来大大减少需要考虑的情况:

    1:要求3节点总是向左倾斜(并且4节点是平衡的)

    2:在递归调用之后,在树的路径上进行旋转

    向左倾斜的要求给出了红黑树和2-3-4树之间的1-1对应关系,并减少了需要考虑的情况数量。

    循环向上旋转策略通过一种自然方式组合各种情况简化了代码(以及我们对它的理解),这两种方法并不是什么新方法,但是二者结合在一起在减少代码数量方面却出奇的有效。

    自顶向下的2-3-4树插入一个新节点,我们翻转颜色以分割在树下的路径上遇到的任何4节点并并进行旋转以平衡4节点(消除在树上出现的连续的红色链接)。这种方法是很自然的,因为分裂4节点以确保搜索不会在4节点上终止,意味着可以通过附加红色链接添加新节点,并平衡4节点数量,平衡4节点的三种方式如下面的图片所示。如果传递的红色连接恰好在3节点中向右倾斜,我们在遇到它时会纠正这种情况

    2-3树值得注意的时,在上面描述的自上而下的2-3-4树实现中,将颜色翻转移动到最后,产生了2-3树的实现,我们将通过颜色翻转,向树传递红色连接,以及在树中移动时以完全相同的方式处理这样做的效果

    在左倾红黑树中传递一个红色节点

    在这里插入图片描述

    public class LLRB<Key extends Comparable<Key>, Value> {   
    
    	private static final boolean RED   = true;  
    	private static final boolean BLACK = false;
    	private Node root;
    	private class Node{     
    		private Key key;     
    		private Value val;     
    		private Node left, right;      
    		private boolean color;      //用一位字段表示颜色
    		Node(Key key, Value val){         
    			this.key = key;  
    			this.val = val;        
    			this.color = RED;     //新节点总是红色
    
    		}   
    	}
    
    	public Value search(Key key){      
    
    		Node x = root;     
    		while (x != null){        
    			int cmp = key.compareTo(x.key);         
    			if (cmp == 0) return x.val;         
    			else if (cmp < 0) x = x.left;         
    			else if (cmp > 0) x = x.right;      
    		}      
    		return null;   
    	}
    	
    	public void insert(Key key, Value value){       
    		root = insert(root, key, value);       
    		root.color = BLACK;  
    	}   
    
    	private Node insert(Node h, Key key, Value value){       
    		if (h == null) return new Node(key, value);
    		if (isRed(h.left) && isRed(h.right)) colorFlip(h);  //这一行开始	
    		int cmp = key.compareTo(h.key);  
    		if (cmp == 0) h.val = value;       
    		else if (cmp < 0) h.left =  insert(h.left, key, value);      
    		else h.right = insert(h.right, key, value);
    		if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);       
    		if (isRed(h.left) && isRed(h.left.left)) h =rotateRight(h);  //到这里运行结束时,得到2-3树
    		return h;   
    	} 
    } 
    
    

    删除

    在许多符号表实现中,删除操作的高效实现是一个挑战,红黑树也不例外,工业级的实现可以运行超过100行代码。教科书一般以详细的案例研究的方式描述操作,避免完整的实现

    下面的代码是LLRB 2-3树的delete()完整实现,它是基于反向自顶向下的方法用于插入2-3-4树:

    我们进行旋转和颜色翻转向下搜索路径,以确保搜索不会在2节点上结束,这样我们就可以删除底部节点,我们使用fixUp()方法共享insert()代码中递归调用后的颜色翻转和旋转代码,通过fixUp(),我们可以在搜索路径上留下右倾斜的红色链接和不平衡的四个节点,确保这些问题在沿树上升的时候会被修复(这种方法也适用于2-3-4树,但如果搜索路径上的右节点是4节点,则需要额外的旋转。)

    作为热身,考虑删除最小操作,目标是删除左边脊柱(left spine)的底部节点,同时保持平衡。为此,我们维护当前节点或者其左孩子的红色不变式,我们可以通过向左移动(move to the left)来实现,除非当前节点是红色的,其左孩子和左孙子(left grandchild,还是叫左孩子的左孩子合适一些?)都是黑的。在这种情况下我们可以做一个颜色翻转,它可以恢复不变量,但可能会在右边引入连续的红色节点,在这种情况下,我们可以通过两个旋转和一个颜色翻转来修正条件,这些操作是在下面的moveRedLeft()方法中实现的。

    使用moveRedLeft()使得deleteMin()的递归实现非常简单,对于一般的删除,我们还需要moveRedRight(),它与moveRedLeft()类似,但是更简单,并且我们需要在搜索路径上将左边的红色链接旋转到右侧以保持不变量。如果要删除的节点是内部节点,我们将其键和值字段替换为其右子树中的最小节点字段,然后删除右子树中最小值字段(或者我们可以重新安排指针来使用节点而不是复制字段)。

    在下面给出了本文所讨论的delete()的完整实现,它使用的代码量仅仅是红黑树典型实现的三分之一到四分之一,使用LLRB树,我们可以设计出简洁的代码,而且具有对数级别的性能保证,还不会使用额外的空间

    删除左倾红黑 2-3树的最小值代码(Delete-the-minimum code for LLRB 2-3 trees)

    
    public void deleteMin() {   
    	root = deleteMin(root);  
    	root.color = BLACK;
     }
    
    private Node deleteMin(Node h) {   
    	if (h.left == null) return null;
    	if (!isRed(h.left) && !isRed(h.left.left))h = moveRedLeft(h);
    	h.left = deleteMin(h.left);
    	return fixUp(h); 
    } 
    
    

    从左倾红黑 2-3树中删除节点(Delete code for LLRB 2-3 trees)

     private Node moveRedLeft(Node h){
    	colorFlip(h);      
        if(isRed(h.right.left)){ 
       	 h.right =rotateRight(h.right);  
       	 h =rotateLeft(h);        
       	 colorFlip(h);     
        }     
    return h;  
    }
    
    private Node moveRedRight(Node h){  
       colorFlip(h);       
       if (isRed(h.left.left)){   
       	h = rotateRight(h);   
       	colorFlip(h);     
       }      	
        return h;  
    }
    
     
    public void delete(Key key){ 
       root = delete(root, key); 
       root.color = BLACK;   
     }
    
    private Node delete(Node h, Key key){ 
       if (key.compareTo(h.key) < 0){             
       	if (!isRed(h.left) && !isRed(h.left.left)) h = moveRedLeft(h);              
       	h.left =  delete(h.left, key);         
       } else {     
       	if (isRed(h.left)) h = rotateRight(h); 
       	if (key.compareTo(h.key) == 0 && (h.right == null)) return null;              
       	if (!isRed(h.right) && !isRed(h.right.left)) h = moveRedRight(h);           
    
       if (key.compareTo(h.key) == 0){      
       	h.val = get(h.right, min(h.right).key);            
       	h.key = min(h.right).key;                   
       	h.right = deleteMin(h.right);             
       }else h.right = delete(h.right, key);  
    }
    return fixUp(h); 
    }
    

    图示:

    在这里插入图片描述

    展开全文
  • 红黑树不追求"完全平衡",即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡,但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内...

    RB-Tree和AVL树作为BBST,其实现的算法时间复杂度相同,AVL作为最先提出的BBST,貌似RB-tree实现的功能都可以用AVL树是代替,那么为什么还需要引入RB-Tree呢?

    1. 红黑树不追求"完全平衡",即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡,但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决,而AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多。
    2. 就插入节点导致树失衡的情况,AVL和RB-Tree都是最多两次树旋转来实现复衡rebalance,旋转的量级是O(1)
      删除节点导致失衡,AVL需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而RB-Tree最多只需要旋转3次实现复衡,只需O(1),所以说RB-Tree删除节点的rebalance的效率更高,开销更小!
    3. AVL的结构相较于RB-Tree更为平衡,插入和删除引起失衡,如2所述,RB-Tree复衡效率更高;当然,由于AVL高度平衡,因此AVL的Search效率更高啦。
    4. 针对插入和删除节点导致失衡后的rebalance操作,红黑树能够提供一个比较"便宜"的解决方案,降低开销,是对search,insert ,以及delete效率的折衷,总体来说,RB-Tree的统计性能高于AVL.
    5. 故引入RB-Tree是功能、性能、空间开销的折中结果。
      5.1 AVL更平衡,结构上更加直观,时间效能针对读取而言更高;维护稍慢,空间开销较大。
      5.2 红黑树,读取略逊于AVL,维护强于AVL,空间开销与AVL类似,内容极多时略优于AVL,维护优于AVL。
      基本上主要的几种平衡树看来,红黑树有着良好的稳定性和完整的功能,性能表现也很不错,综合实力强,在诸如STL的场景中需要稳定表现。
      红黑树的查询性能略微逊色于AVL树,因为其比AVL树会稍微不平衡最多一层,也就是说红黑树的查询性能只比相同内容的AVL树最多多一次比较,但是,红黑树在插入和删除上优于AVL树,AVL树每次插入删除会进行大量的平衡度计算,而红黑树为了维持红黑性质所做的红黑变换和旋转的开销,相较于AVL树为了维持平衡的开销要小得多

    总结:实际应用中,若搜索的次数远远大于插入和删除,那么选择AVL,如果搜索,插入删除次数几乎差不多,应该选择RB。

    参考:https://www.jianshu.com/p/37436ed14cc6

    展开全文
  • 本文将从最普通的二叉查找开始,逐步说明各种解决的问题以及面临的新问题,从而说明MySQL为什么选择B+作为索引结构。 一、二叉查找(BST):不平衡 二叉查找(BST,Binary Search Tree),也叫二叉排序,...

    前言

    在MySQL中,无论是Innodb还是MyIsam,都使用了B+树作索引结构(这里不考虑hash等其他索引)。本文将从最普通的二叉查找树开始,逐步说明各种树解决的问题以及面临的新问题,从而说明MySQL为什么选择B+树作为索引结构。

    一、二叉查找树(BST):不平衡

    二叉查找树(BST,Binary Search Tree),也叫二叉排序树,在二叉树的基础上需要满足:任意节点的左子树上所有节点值不大于根节点的值,任意节点的右子树上所有节点值不小于根节点的值。如下是一颗BST(图片来源)。

     

     

    当需要快速查找时,将数据存储在BST是一种常见的选择,因为此时查询时间取决于树高,平均时间复杂度是O(lgn)。然而,BST可能长歪而变得不平衡,如下图所示(图片来源),此时BST退化为链表,时间复杂度退化为O(n)。

    为了解决这个问题,引入了平衡二叉树。

     

     

    二、平衡二叉树(AVL):旋转耗时

    AVL树是严格的平衡二叉树,所有节点的左右子树高度差不能超过1;AVL树查找、插入和删除在平均和最坏情况下都是O(lgn)。

    AVL实现平衡的关键在于旋转操作:插入和删除可能破坏二叉树的平衡,此时需要通过一次或多次树旋转来重新平衡这个树。当插入数据时,最多只需要1次旋转(单旋转或双旋转);但是当删除数据时,会导致树失衡,AVL需要维护从被删除节点到根节点这条路径上所有节点的平衡,旋转的量级为O(lgn)。

    由于旋转的耗时,AVL树在删除数据时效率很低;在删除操作较多时,维护平衡所需的代价可能高于其带来的好处,因此AVL实际使用并不广泛。

    三、红黑树:树太高

    与AVL树相比,红黑树并不追求严格的平衡,而是大致的平衡:只是确保从根到叶子的最长的可能路径不多于最短的可能路径的两倍长。从实现来看,红黑树最大的特点是每个节点都属于两种颜色(红色或黑色)之一,且节点颜色的划分需要满足特定的规则(具体规则略)。红黑树示例如下(图片来源):

     

     

    与AVL树相比,红黑树的查询效率会有所下降,这是因为树的平衡性变差,高度更高。但红黑树的删除效率大大提高了,因为红黑树同时引入了颜色,当插入或删除数据时,只需要进行O(1)次数的旋转以及变色就能保证基本的平衡,不需要像AVL树进行O(lgn)次数的旋转。总的来说,红黑树的统计性能高于AVL。

    因此,在实际应用中,AVL树的使用相对较少,而红黑树的使用非常广泛。例如,Java中的TreeMap使用红黑树存储排序键值对;Java8中的HashMap使用链表+红黑树解决哈希冲突问题(当冲突节点较少时,使用链表,当冲突节点较多时,使用红黑树)。

    对于数据在内存中的情况(如上述的TreeMap和HashMap),红黑树的表现是非常优异的。但是对于数据在磁盘等辅助存储设备中的情况(如MySQL等数据库),红黑树并不擅长,因为红黑树长得还是太高了。当数据在磁盘中时,磁盘IO会成为最大的性能瓶颈,设计的目标应该是尽量减少IO次数;而树的高度越高,增删改查所需要的IO次数也越多,会严重影响性能。

    四、B树:为磁盘而生

    B树也称B-树(其中-不是减号),是为磁盘等辅存设备设计的多路平衡查找树,与二叉树相比,B树的每个非叶节点可以有多个子树。因此,当总节点数量相同时,B树的高度远远小于AVL树和红黑树(B树是一颗“矮胖子”),磁盘IO次数大大减少。

    定义B树最重要的概念是阶数(Order),对于一颗m阶B树,需要满足以下条件:

    • 每个节点最多包含 m 个子节点。
    • 如果根节点包含子节点,则至少包含 2 个子节点;除根节点外,每个非叶节点至少包含 m/2 个子节点。
    • 拥有 k 个子节点的非叶节点将包含 k - 1 条记录。
    • 所有叶节点都在同一层中。

    可以看出,B树的定义,主要是对非叶结点的子节点数量和记录数量的限制。

    下图是一个3阶B树的例子(图片来源):

     

     

    B树的优势除了树高小,还有对访问局部性原理的利用。所谓局部性原理,是指当一个数据被使用时,其附近的数据有较大概率在短时间内被使用。B树将键相近的数据存储在同一个节点,当访问其中某个数据时,数据库会将该整个节点读到缓存中;当它临近的数据紧接着被访问时,可以直接在缓存中读取,无需进行磁盘IO;换句话说,B树的缓存命中率更高。

    B树在数据库中有一些应用,如mongodb的索引使用了B树结构。但是在很多数据库应用中,使用了是B树的变种B+树。

    五、B+树

    B+树也是多路平衡查找树,其与B树的区别主要在于:

    • B树中每个节点(包括叶节点和非叶节点)都存储真实的数据,B+树中只有叶子节点存储真实的数据,非叶节点只存储键。在MySQL中,这里所说的真实数据,可能是行的全部数据(如Innodb的聚簇索引),也可能只是行的主键(如Innodb的辅助索引),或者是行所在的地址(如MyIsam的非聚簇索引)。
    • B树中一条记录只会出现一次,不会重复出现,而B+树的键则可能重复重现——一定会在叶节点出现,也可能在非叶节点重复出现。
    • B+树的叶节点之间通过双向链表链接。
    • B树中的非叶节点,记录数比子节点个数少1;而B+树中记录数与子节点个数相同。

    由此,B+树与B树相比,有以下优势:

    • 更少的IO次数:B+树的非叶节点只包含键,而不包含真实数据,因此每个节点存储的记录个数比B数多很多(即阶m更大),因此B+树的高度更低,访问时所需要的IO次数更少。此外,由于每个节点存储的记录数更多,所以对访问局部性原理的利用更好,缓存命中率更高。
    • 更适于范围查询:在B树中进行范围查询时,首先找到要查找的下限,然后对B树进行中序遍历,直到找到查找的上限;而B+树的范围查询,只需要对链表进行遍历即可。
    • 更稳定的查询效率:B树的查询时间复杂度在1到树高之间(分别对应记录在根节点和叶节点),而B+树的查询复杂度则稳定为树高,因为所有数据都在叶节点。

    B+树也存在劣势:由于键会重复出现,因此会占用更多的空间。但是与带来的性能优势相比,空间劣势往往可以接受,因此B+树的在数据库中的使用比B树更加广泛。

    六、B+树的魅力

    前面说到,B树/B+树与红黑树等二叉树相比,最大的优势在于树高更小。实际上,对于Innodb的B+索引来说,树的高度一般在2-4层。下面来进行一些具体的估算。

    树的高度是由阶数决定的,阶数越大树越矮;而阶数的大小又取决于每个节点可以存储多少条记录。Innodb中每个节点使用一个页(page),页的大小为16KB,其中元数据只占大约128字节左右(包括文件管理头信息、页面头信息等等),大多数空间都用来存储数据。

    • 对于非叶节点,记录只包含索引的键和指向下一层节点的指针。假设每个非叶节点页面存储1000条记录,则每条记录大约占用16字节;当索引是整型或较短的字符串时,这个假设是合理的。延伸一下,我们经常听到建议说索引列长度不应过大,原因就在这里:索引列太长,每个节点包含的记录数太少,会导致树太高,索引的效果会大打折扣,而且索引还会浪费更多的空间。
    • 对于叶节点,记录包含了索引的键和值(值可能是行的主键、一行完整数据等,具体见前文),数据量更大。这里假设每个叶节点页面存储100条记录(实际上,当索引为聚簇索引时,这个数字可能不足100;当索引为辅助索引时,这个数字可能远大于100;可以根据实际情况进行估算)。

    对于一颗3层B+树,第一层(根节点)有1个页面,可以存储1000条记录;第二层有1000个页面,可以存储1000*1000条记录;第三层(叶节点)有1000*1000个页面,每个页面可以存储100条记录,因此可以存储1000*1000*100条记录,即1亿条。而对于二叉树,存储1亿条记录则需要26层左右。

    七、总结

    展开全文
  • 1、二叉查找(Binary Search Tree) 很显然,二叉查找的发现完全是因为静态查找结构在动态插入,删除结点所表现出来的无能为力(需要付出极大的代价)。 BST的操作代价分析: (1) 查找代价: 任何一个数据的查找...
  • 红黑树详解

    千次阅读 多人点赞 2021-02-04 16:16:43
    红黑树是一种二叉搜索树,是AVL树的改进版。 红黑树的生长是自底向上的,跟2-3树类似 为啥引入红黑树: 1、二插搜索树会出现退化成链表的情况,其时间复杂度为O(n) 2、为防止二叉搜索树会退化成链表,引入了对左右...
  • 红黑树源码讲解之手写红黑树 树入门 什么是树 树(tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合。 把它叫做“树...
  • 红黑树&二叉树

    2021-01-22 18:20:44
    红黑树了解二叉查找树二叉树特点二叉查找树缺点红黑树红黑树特点红黑树自平衡操作左旋右旋变色红黑树查找流程红黑树插入流程红黑树删除 了解二叉查找树 二叉树特点 左子树上所有的节点值均小于或等于他的根节点的值...
  • 研究红黑树

    2019-03-30 14:08:11
    文章目录红黑树剖析起点-二叉查找树二叉查找树的特点是二叉查找数的缺点引入红黑树红黑树时间复杂度为O(logn) 且,一个含n个节点的红黑树的高度至多为 2log(n+1)特性分析左旋分析右旋put 插入节点过程remove 删除...
  • 红黑树和AVL树的比较

    千次阅读 2017-08-14 15:58:05
    红黑树和AVL树的比较这篇文章不是对红黑树和AVL树基本理论的讲解,更多的是关注为何红黑树和AVL树相比较的优缺点。读者应该之前就已经了解到红黑树和AVL树的相关基础知识。
  • 简单理解红黑树

    2021-03-04 09:47:08
    比如说遍历,二分查找,哈希等,其中我们知道哈希在一定情况下可以达到O(1)的时间复杂度,速度可谓是非常之快,但是他也有他的缺点就是不能范围查找,所以我们就来说说今天要说的红黑树。 二叉查找树 说到红黑树,...
  • 红黑树讲解

    2019-07-29 17:22:22
    定义:红黑树是一种含有红黑节点并能自平衡的二叉查找树,在进行插入和删除等可能会破坏树的平衡的操作时,需要重新自调整达到平衡状态,这里平衡的含义是保证最长路径不超过最短路径的两倍。红黑树是一种非严格平衡...
  • 三、红黑树1、红黑树概念2、红黑树的特点3、红黑树的定义4、红黑树中的操作5、红黑树插入情景分析四、手写一棵红黑树1、代码2、插入测试 在学习红黑树的实现原理之前,首先要明白为什么会出现红黑树?它是怎么来的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,020
精华内容 10,408
关键字:

红黑树缺点