New York Institute of Technology, Manhattan**We aren't endorsed by this school
Course
CSCI 507
Subject
Computer Science
Date
Dec 18, 2024
Pages
23
Uploaded by AgentExplorationHamster52
Lecture Notes 7Data StructuresSpring 2022CSCI 260Prof. F. FischmanRed-Black TreesAVL Trees and Red-Black Trees are both self-balancing BSTs, but they differ in terms of their balancing strategies and theproperties they maintain. Here are the key differences between AVL Trees and Red-Black Trees:Balancing Strategy:AVL Trees:AVL Trees use a stricter balancing strategy. They ensure that the balance factor (the height differencebetween left and right subtrees) for every node is at most 1, which results in a balanced tree. AVL Trees require more rotations to maintain this strict balance, making them slightly more rigid but potentially morebalanced.Red-Black Trees:Red-Black Trees use a more relaxed balancing strategy. They ensure that certain properties aremaintained, such as ensuring that no two consecutive nodes are red and that the black height of every path from theroot to any leaf node is the same. While this doesn't guarantee perfect balance, it does ensure that the tree remainsrelatively balanced and requires fewer rotations.Rotation Operations:AVL Trees:AVL Trees may require more rotation operations during insertion and deletion to maintain balance. Theserotations are LL (Left-Left), LR (Left-Right), RR (Right-Right), and RL (Right-Left) rotations.Red-Black Trees:Red-Black Trees typically require fewer rotations compared to AVL Trees. The primary rotations usedare left rotations and right rotations to maintain the Red-Black properties.Height:AVL Trees: AVL Trees tend to have a more balanced height due to their strict balancing criteria. The height is guaranteedto be logarithmic in the number of nodes.Red-Black Trees: Red-Black Trees may have a slightly larger height on average compared to AVL Trees but still maintain aheight that is logarithmic in the number of nodes.Memory Overhead:AVL Trees: AVL Trees require more memory to store additional height information for each node, as they need tomaintain a strict balance.Red-Black Trees:Red-Black Trees have a smaller memory overhead compared to AVL Trees, making them morememory-efficient.Performance:AVL Trees:AVL Trees tend to have slightly faster lookup times than Red-Black Trees due to their stricter balancing.However, the cost of maintaining balance through rotations can make insertion and deletion slightly slower.
Red-Black Trees: Red-Black Trees are efficient for insertion and deletion operations, especially in cases where theseoperations are frequent. They are often favored in scenarios like databases where data is frequently modified.A BST with the following extra characteristics is known as a red-black tree:Both red and black are used to color each node.Black marks the rootThe "no multiple reds" rule states that a red node cannot have another red child. There are exactly as many black nodeson each path that leads to a null, which is known as the "equal exit cost".Naturally, the nodes aren't colored in reality. Each node only sports a flag designating whether it is regarded as red orblack.Example: Valid Red-Black TreeThe root node (10) is black.There are no two consecutive red nodes along any path (no red node has a red child).If you examine any path from the root to a null (e.g., from 10 to 2 or from 20 to 35), you will see that there is the samenumber of black nodes along each path (2 black nodes).This tree satisfies all the Red-Black tree properties and is valid.
Example: Invalid Red-Black Tree The path from the node with value 30 to the node with value 35 violates the "no multiple reds" rule because there aretwo consecutive red nodes (30 and 35) along this path. This tree does not satisfy the Red-Black tree properties and isinvalid.In practical implementations, red nodes are typically represented using a single bit or flag (e.g., a boolean variable)associated with each node, rather than explicitly storing a color attribute, to minimize memory usage making themsuitable for practical implementations in various data structures and algorithms.Example: Consider a Red-Black treeWe represent the color of each node using a single bit. Here's how the tree would look in memory:Node: 10 (Black)- Color: 0 (Black)- Left: Pointer to Node 5- Right: Pointer to Node 20- Value: 10Node: 5 (Red)- Color: 1 (Red)- Left: Pointer to Node 2- Right: Pointer to Node 7- Value: 5Node: 20 (Red)- Color: 1 (Red)- Left: Pointer to Node 15- Right: Pointer to Node 30- Value: 20
Node: 2 (Black)- Color: 0 (Black)- Left: Null- Right: Null- Value: 2Node: 7 (Black)- Color: 0 (Black)- Left: Null- Right: Null- Value: 7Node: 15 (Black)- Color: 0 (Black)- Left: Null- Right: Null- Value: 15Node: 30 (Black)- Color: 0 (Black)- Left: Null- Right: Pointer to Node 35- Value: 30Node: 35 (Red)- Color: 1 (Red)- Left: Null- Right: Null- Value: 35Each node has a color attribute that requires only a single bit to indicate red or black. The left and right attributes pointto the child nodes, and the value attribute stores the value associated with each node. The color bits are 0 for black and1 for red.In practical implementations, black nodes are typically represented using a single bit or flag (e.g., a boolean variable)associated with each node, rather than explicitly storing a color attribute. This approach minimizes memory usage whilestill ensuring proper balancing.In a Red-Black tree, instead of explicitly storing a color attribute, you can use a single bit to indicate whether a node isblack. This color bit can be a boolean variable, where false represents black and true represents red. This way, eachnode only requires an extra bit to store its color, which is efficient in terms of memory usage.Example: Consider a Red-Black tree:
We represent the color of each node using a single bit, with false indicating black and true indicating red. Here's how thetree would look in memory:Node: 10- Color Bit: false (Black)- Left: Pointer to Node 5- Right: Pointer to Node 20- Value: 10Node: 5- Color Bit: false (Black)- Left: Pointer to Node 2- Right: Pointer to Node 7- Value: 5Node: 20- Color Bit: true (Red)- Left: Pointer to Node 15- Right: Pointer to Node 30- Value: 20Node: 2- Color Bit: false (Black)- Left: Null- Right: Null- Value: 2Node: 7- Color Bit: false (Black)- Left: Null- Right: Null- Value: 7Node: 15- Color Bit: false (Black)- Left: Null- Right: Null- Value: 15Node: 30- Color Bit: false (Black)
- Left: Null- Right: Pointer to Node 35- Value: 30Node: 35- Color Bit: true (Red)- Left: Null- Right: Null- Value: 35Each node has a single color bit attribute, which requires only a single bit to indicate whether it is black (false) or red(true).The left and right attributes point to the child nodes, and the value attribute stores the value associated with each node.The color bit is false for black nodes and true for red nodes.It is more practical, to think of each node as a toll booth rather than the colors. The black toll booths cost $1 each, butthe red toll booths are free as you move from the root to one of the null references (an exit). No matter which exit youchoose, the cost of the trip will be the same, according to the "same exit cost" criterion.Many authors choose to substitute dummy black leaves for the nulls because they are a bit of a hassle. Next, eitherevery node is one of those dummy leaves or has two children. In an algorithms course, it's nice that the most succinct descriptions condense red-black trees to 2-4 trees, but here is asimpler way of doing it.Think of AVL Trees
You add a node as usual and give it the color red. If its parent is also red, rearrange according to the illustration. The rednode continues all the way to the root. If necessary, repeat. Color the red node black if it reaches the root.How come it works? The cost of passing through the nodes remains the same after the transformation; it is $1 both before and after. If itcomes to that, altering the root from red to black simply raises the cost of each journey by $1.Use the normal removal procedure for BSTs first, just like with insertion. Keep in mind that the eliminated node in thatalgorithm has just one child at most. A node with two children is never removed; instead, it is filled with the value of anode with one child or less before the other node is eliminated.It's simple in two circumstances. The removal is not problematic if the node to be removed is red because the final treewill still be a red-black tree. Next, suppose the node that is being removed has a child. The child must be red in order tocomply with the "same exit cost" requirement. Just make the child black and take away the parent.The removal of a black leaf presents a challenging situation. It would be too cheap to replace it with a null if we simplyremoved it. Rather, we'll first make it a red node. First carry out the safe removal, then transform. In this way, nulls anddummy leaves won't be an issue.The black leaf X should be eliminated from six different spots. Keep in mind that a black leaf must always have a sibling,and a red parent cannot have a red sibling.
Temporarily "bubble up" the expenses by increasing the cost of the parent by $1 and decreasing the cost of the childrenby $1 in order to change a black node into a red one.It is obvious that "bubbling up" keeps all path costs constant.Bubbling up simply changes the red node into a black one and the black ones become red ones in the first column of thesix situations mentioned above. The red one is taken out. With one of its offspring, the other might result in a double-red violation, in which case we repair it. But in the other situations, a fresh issue appears. Nodes with prices of 2 or -1are what are referred to as double-black and negative-red, respectively. In the analogy of the toll booth, a double-blacknode costs $2, and every time you pass through a negative-red node, you receive $1. These are obviously invalid nodesin a red-black tree, so we must remove them.The transformation depicted below, or its mirror counterpart, can delete the pair since a negative-red node is always achild of a double-black node.The development of a double-black node can occasionally result in a double-red violation below. By using the transformbroadly, we may correct the double-red violation. Any cost that the gray node has is lowered by $1.
The preservation of all trip expenses by both transformations can be easily verified. When neither of the twotransformations is applicable, we must occasionally "bubble up" once more, bringing the double-black node closer to theroot.We can swap out the double-black node for a standard black node if it reaches the root.import java.util.ArrayList;import java.util.List;
public class RBTree{Node rootRBT; // Package access, for testingstatic final int BLK = 1;static final int Red = 0;private static final int Neg_Red = -1;private static final int Double_BLK = 2;public RBTree(){rootRBT = null;}public void addRBT(Comparable objRBT){Node newNodeRBT = new Node();newNodeRBT.data = objRBT;newNodeRBT.leftRBT = null;newNodeRBT.rightRBT = null;if (rootRBT == null) { rootRBT = newNodeRBT; }else { rootRBT.addNodeRBT(newNodeRBT); }fixAfterAddRBT(newNodeRBT);}public boolean find(Comparable objRBT){Node currentRBT = rootRBT;while (currentRBT != null){int dRBT = currentRBT.dataRBT.compareTo(objRBT);if (dRBT == 0) return true;else if (dRBT > 0) currentRBT = currentRBT.leftRBT;else currentRBT = currentRBT.rightRBT;}return false;}public void remove(Comparable obj){Node beRemovedRBT = rootRBT;boolean foundRBT = false;while (!foundRBT && beRemovedRBT != null){int dRBT = beRemovedRBT.dataRBT.compareTo(objRBT);if (dRBT == 0) { foundRBT = true; }else{if (dRBT > 0) { beRemovedRBT = beRemovedRBT.leftRBT; }else { beRemovedRBT = beRemovedRBT.rightRBT; }}}