一、红黑树
1、普通的二叉树有一个问题,当插入的数据是有序的时候,二叉树就是非平衡的了,而对于非平衡树它的快速查找(插入、删除)指定数据项的能力就丧失了。红黑树就是一种解决非平衡树的方法,它是增加了某些特点的二叉搜索树。
2、自顶向下插入
自顶向下插入是在搜索例程沿着树向下查找插入点,在此进程中可能要对树的结构做一些改变。
另一种方法是自底向上的插入。它需要找到插入新数据项的位置,然后沿着树向上改变树的结构。自底向上插入效率比较低,这是因为必须顺着树扫描两趟。
二、平衡树和非平衡树
1、先看一下树是怎么变得不平衡的。如下图所示,这些节点都排在一条直线上。若关键字都为升序的,每一个节点都大于上一个插入的节点,每一个节点都是上一个节点的右节点。所有的节点都在树的一侧,这棵树属于极不平衡的情况。
当树没有分支时,它其实是一个链表了,和在链表中一样,现在必须要(平均)查找一半的数据项来寻找要找的数据项。在这种情况下,查找的速度下降到了O(N),而不是平衡树的O(logN)。
2、部分非平衡树
尽管它比最不平衡树要好,但是在这种情况下的查找时间不是最佳的。
3、平衡的补救
为了能以较快的时间O(logN)来搜索一棵树,需要保证树总是平衡的。
红黑树的平衡是在插入的过程中(删除时也是)取得的。对一个要插入的数据项,插入例程要检查不会破坏树一定的特性。如果破坏了,程序就会纠正,根据需要更改树的结构。通过维持树的特征,保持了树的平衡。
三、红-黑树的特征
这种树有两种特征如下:
-
节点都有颜色
-
在插入和删除的过程中,要遵循保持这些颜色的不同排列的规则
带颜色的节点
在红-黑树中,每一个节点或者是黑色的或者是红色的。也可以是任意的两种颜色。实际上所说的节点有颜色是任意的比方,可以使用其他类似方法来表示:比如可以说每一个节点不是阴就是阳。颜色便于标记。在节点中添加一个数据字段,可以是boolean类型的,以此来表示颜色的信息。
红-黑规则
当插入(或者删除)一个新节点时,必须要遵循的一定的规则,它们被称为红-黑规则。如果遵循这些规则,树就是平衡的。如下是规则:
1.每一个节点不是红色就是黑色的。
2.根总是黑色的。
3.如果节点是红色的,则它的子节点必须是黑色的。
4.从根到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点。
规则4中的“空子节点”是指非叶节点可以接子节点的位置。换句话说,就是一个有右子节点的节点的可能接左子节点的位置,或者是有左子节点的节点的可能接右子节点位置。
在从根到叶节点的路径上的黑色节点的数目称为黑色高度(black height)。规则4的另一种陈述方法是所有从根到叶节点路径上的黑色高度必须相同。
重复的关键字
如果有多于一个数据项的关键字值相同,将会出现什么情况呢?把有相同关键字的数据项分配到其他也有相同关键字数据项的两侧是很重要的。这也就是说,如果关键字的序列为50,50,50,要把第二个50放到第一个50的右边,并且把第三个50放到第一个50的左边。否则,树将不平衡。
修正违规的情况
假设看到颜色的规则被违反了。如何修正才能使树遵守上边的规则呢?有且只有两种方法来修正:
-
改变节点的颜色
-
执行旋转操作
左旋的动画:
右旋的动画: