在自下而上的红黑树插入中,使用“简单”的二叉搜索树插入,然后在返回根的过程中纠正RB-Tree违规。借助递归可以很容易地做到这一点。在“自上而下插入”中,在将树向下遍历到插入点的同时进行了更正。实际插入完成后,无需进行任何更正,因此无需遍历树。
因此,“自上而下”插入的目标是以保持RB属性的方式从根部遍历到插入点。因此,这种迭代方法使自上而下的插入比自下而上的插入更快。
用于解决违规和平衡的两个基本操作是-
以下是详细的算法
该算法的主要目标是创建一个插入点,新节点的父节点在此处为黑色,新节点的叔叔在此处为黑色。
令N为要插入的新节点。
- 如果Y和Z为黑色:
执行简单的BST插入。插入新节点N作为Y或Z的左/右子节点,并使新插入的节点的颜色为红色。
- 如果X的父母是黑人:
然后为X,Y,Z重新着色并继续沿树下移。 - X的父母P是红色,祖父母是黑色,X和P都是祖父母G的左或右子代:
- 重新着色X,Y,Z
- 绕G旋转P
- 颜色P黑色
- 颜色G红色
如果存在违规行为,请继续处理其他案件。
- X的父母是红色,祖父母是黑色,X和P是祖父母G的对子
- 重新着色X,Y,Z
- 将X绕P旋转
- 绕G旋转X
- 重新着色X和G
在所需位置插入新节点N。
例子 :
在下面的RB树中插入节点3 –
下面执行以下方法:
Java
// Java implementation for Top-Down
// Red-Black Tree Insertion creating
// a red black tree and storing an
// English sentence into it using Top
// down insertion approach
import static java.lang.Integer.max;
// Class for performing
// RBTree operations
public class RbTree {
TreeNode Root = null;
// Function to calculate
// the height of the tree
int HeightT(TreeNode Root)
{
int lefth, righth;
if (Root == null
|| (Root.children == null
&& Root.children[1] == null)) {
return 0;
}
lefth = HeightT(Root.children[0]);
righth = HeightT(Root.children[1]);
return (max(lefth, righth) + 1);
}
// Function to check if
// dir is equal to 0
int check(int dir)
{
return dir == 0 ? 1 : 0;
}
// Function to check if a
// node's color is red or not
boolean isRed(TreeNode Node)
{
return Node != null
&& Node.color.equals("R");
}
// Function to perform
// single rotation
TreeNode SingleRotate(TreeNode Node,
int dir)
{
TreeNode temp
= Node.children[check(dir)];
Node.children[check(dir)]
= temp.children[dir];
temp.children[dir] = Node;
Root.color = "R";
temp.color = "B";
return temp;
}
// Function to perform double rotation
TreeNode DoubleRotate(TreeNode Node,
int dir)
{
Node.children[check(dir)]
= SingleRotate(Node.children[check(dir)],
check(dir));
return SingleRotate(Node, dir);
}
// Function to insert a new
// node with given data
TreeNode Insert(RbTree tree,
String data)
{
if (tree.Root == null) {
tree.Root
= new TreeNode(data);
if (tree.Root == null)
return null;
}
else {
// A temporary root
TreeNode temp = new TreeNode("");
// Grandparent and Parent
TreeNode g, t;
TreeNode p, q;
int dir = 0, last = 0;
t = temp;
g = p = null;
t.children[1] = tree.Root;
q = t.children[1];
while (true) {
if (q == null) {
// Inserting root node
q = new TreeNode(data);
p.children[dir] = q;
}
// Sibling is red
else if (isRed(q.children[0])
&& isRed(q.children[1])) {
// Recoloring if both
// children are red
q.color = "R";
q.children[0].color = "B";
q.children[1].color = "B";
}
if (isRed(q) && isRed(p)) {
// Resolving red-red
// violation
int dir2;
if (t.children[1] == g) {
dir2 = 1;
}
else {
dir2 = 0;
}
// If children and parent
// are left-left or
// right-right of grand-parent
if (q == p.children[last]) {
t.children[dir2]
= SingleRotate(g,
last == 0
? 1
: 0);
}
// If they are opposite
// childs i.e left-right
// or right-left
else {
t.children[dir2]
= DoubleRotate(g,
last == 0
? 1
: 0);
}
}
// Checking for correct
// position of node
if (q.data.equals(data)) {
break;
}
last = dir;
// Finding the path to
// traverse [Either left
// or right ]
dir = q.data.compareTo(data) < 0
? 1
: 0;
if (g != null) {
t = g;
}
// Rearranging pointers
g = p;
p = q;
q = q.children[dir];
}
tree.Root = temp.children[1];
}
// Assign black color
// to the root node
tree.Root.color = "B";
return tree.Root;
}
// Print nodes at each
// level in level order
// traversal
void PrintLevel(TreeNode root, int i)
{
if (root == null) {
return;
}
if (i == 1) {
System.out.print("| "
+ root.data
+ " | "
+ root.color
+ " |");
if (root.children[0] != null) {
System.out.print(" "
+ root.children[0].data
+ " |");
}
else {
System.out.print(" "
+ "NULL"
+ " |");
}
if (root.children[1] != null) {
System.out.print(" "
+ root.children[1].data
+ " |");
}
else {
System.out.print(" "
+ "NULL"
+ " |");
}
System.out.print(" ");
return;
}
PrintLevel(root.children[0],
i - 1);
PrintLevel(root.children[1],
i - 1);
}
// Utility Function to
// perform level order
// traversal
void LevelOrder(TreeNode root)
{
int i;
for (i = 1;
i < HeightT(root) + 1;
i++) {
PrintLevel(root, i);
System.out.print("\n\n");
}
}
}
// Class for representing
// a node of the tree
class TreeNode {
// Class variables
String data, color;
TreeNode children[];
public TreeNode(String data)
{
// Color R- Red
// and B - Black
this.data = data;
this.color = "R";
children
= new TreeNode[2];
children[0] = null;
children[1] = null;
}
}
// Driver Code
class Driver {
public static void main(String[] args)
{
// Tree Node Representation
// -------------------------------------------
// DATA | COLOR | LEFT CHILD | RIGHT CHILD |
// -------------------------------------------
RbTree Tree = new RbTree();
String Sentence, Word;
Sentence = "old is gold";
String Word_Array[]
= Sentence.split(" ");
for (int i = 0;
i < Word_Array.length;
i++) {
Tree.Root
= Tree.Insert(Tree,
Word_Array[i]);
}
// Print Level Order Traversal
System.out.println("The Level"
+ "Order Traversal"
+ "of the tree is:");
Tree.LevelOrder(Tree.Root);
System.out.println("\nInserting a"
+ " word in the tree:");
Word = "forever";
Tree.Root = Tree.Insert(Tree,
Word);
System.out.println("");
Tree.LevelOrder(Tree.Root);
}
}
C#
// C# implementation for Top-Down
// Red-Black Tree Insertion creating
// a red black tree and storing an
// English sentence into it using Top
// down insertion approach
using System;
// Class for performing
// RBTree operations
class RbTree
{
public TreeNode Root = null;
// Function to calculate
// the height of the tree
public int HeightT(TreeNode Root)
{
int lefth, righth;
if (Root == null ||
(Root.children == null &&
Root.children[1] == null))
{
return 0;
}
lefth = HeightT(Root.children[0]);
righth = HeightT(Root.children[1]);
return (Math.Max(lefth, righth) + 1);
}
// Function to check if
// dir is equal to 0
public int check(int dir)
{
return dir == 0 ? 1 : 0;
}
// Function to check if a
// node's color is red or not
public bool isRed(TreeNode Node)
{
return Node != null &&
Node.color.Equals("R");
}
// Function to perform
// single rotation
public TreeNode SingleRotate(TreeNode Node, int dir)
{
TreeNode temp = Node.children[check(dir)];
Node.children[check(dir)] = temp.children[dir];
temp.children[dir] = Node;
Root.color = "R";
temp.color = "B";
return temp;
}
// Function to perform double rotation
public TreeNode DoubleRotate(TreeNode Node, int dir)
{
Node.children[check(dir)] =
SingleRotate(Node.children[check(dir)],
check(dir));
return SingleRotate(Node, dir);
}
// Function to insert a new
// node with given data
public TreeNode Insert(RbTree tree,
String data)
{
if (tree.Root == null)
{
tree.Root = new TreeNode(data);
if (tree.Root == null)
return null;
}
else
{
// A temporary root
TreeNode temp = new TreeNode("");
// Grandparent and Parent
TreeNode g, t;
TreeNode p, q;
int dir = 0, last = 0;
t = temp;
g = p = null;
t.children[1] = tree.Root;
q = t.children[1];
while (true)
{
if (q == null)
{
// Inserting root node
q = new TreeNode(data);
p.children[dir] = q;
}
// Sibling is red
else if (isRed(q.children[0]) &&
isRed(q.children[1]))
{
// Recoloring if both
// children are red
q.color = "R";
q.children[0].color = "B";
q.children[1].color = "B";
}
if (isRed(q) && isRed(p))
{
// Resolving red-red
// violation
int dir2;
if (t.children[1] == g)
{
dir2 = 1;
}
else
{
dir2 = 0;
}
// If children and parent
// are left-left or
// right-right of grand-parent
if (q == p.children[last])
{
t.children[dir2] =
SingleRotate(g, last == 0 ? 1 : 0);
}
// If they are opposite
// childs i.e left-right
// or right-left
else
{
t.children[dir2] =
DoubleRotate(g, last == 0 ? 1 : 0);
}
}
// Checking for correct
// position of node
if (q.data.Equals(data))
{
break;
}
last = dir;
// Finding the path to
// traverse [Either left
// or right ]
dir = q.data.CompareTo(data) < 0 ? 1 : 0;
if (g != null)
{
t = g;
}
// Rearranging pointers
g = p;
p = q;
q = q.children[dir];
}
tree.Root = temp.children[1];
}
// Assign black color
// to the root node
tree.Root.color = "B";
return tree.Root;
}
// Print nodes at each
// level in level order
// traversal
public void PrintLevel(TreeNode root, int i)
{
if (root == null)
{
return;
}
if (i == 1)
{
Console.Write("| " + root.data +
" | " + root.color + " |");
if (root.children[0] != null)
{
Console.Write(" " +
root.children[0].data + " |");
}
else
{
Console.Write(" " + "NULL" + " |");
}
if (root.children[1] != null)
{
Console.Write(" " +
root.children[1].data + " |");
}
else
{
Console.Write(" " + "NULL" + " |");
}
Console.Write(" ");
return;
}
PrintLevel(root.children[0], i - 1);
PrintLevel(root.children[1], i - 1);
}
// Utility Function to perform
// level order traversal
public void LevelOrder(TreeNode root)
{
int i;
for (i = 1; i < HeightT(root) + 1; i++)
{
PrintLevel(root, i);
Console.Write("\n\n");
}
}
}
// Class for representing
// a node of the tree
public class TreeNode
{
// Class variables
public String data, color;
public TreeNode []children;
public TreeNode(String data)
{
// Color R- Red
// and B - Black
this.data = data;
this.color = "R";
children = new TreeNode[2];
children[0] = null;
children[1] = null;
}
}
// Driver Code
public class Driver
{
public static void Main(String[] args)
{
// Tree Node Representation
// -------------------------------------------
// DATA | COLOR | LEFT CHILD | RIGHT CHILD |
// -------------------------------------------
RbTree Tree = new RbTree();
String Sentence, Word;
Sentence = "old is gold";
char[] spearator = { ' ', ' ' };
String []Word_Array = Sentence.Split(spearator,
StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < Word_Array.Length; i++)
{
Tree.Root = Tree.Insert(Tree,
Word_Array[i]);
}
// Print Level Order Traversal
Console.WriteLine("The Level" +
"Order Traversal" +
"of the tree is:");
Tree.LevelOrder(Tree.Root);
Console.WriteLine("\nInserting a" +
" word in the tree:");
Word = "forever";
Tree.Root = Tree.Insert(Tree, Word);
Console.WriteLine("");
Tree.LevelOrder(Tree.Root);
}
}
// This code is contributed by Rajput-Ji
输出:
The LevelOrder Traversalof the tree is:
| is | B | gold | old |
| gold | R | NULL | NULL | | old | R | NULL | NULL |
Inserting a word in the tree:
| is | B | gold | old |
| gold | B | forever | NULL | | old | B | NULL | NULL |
| forever | R | NULL | NULL |
参考:
红黑树– UMBC CSEE
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。