0% found this document useful (0 votes)
2 views

Unit II

Red-black trees are a type of binary search tree that maintain balance through color properties and rotations, ensuring efficient search, insertion, and deletion operations. Each node has a color attribute (red or black) and specific properties that must be upheld, including that no two red nodes can be adjacent. Rotations are necessary to resolve conflicts and maintain the tree's balance, while augmenting data structures can enhance functionality for complex queries.

Uploaded by

aditigzp2005
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Unit II

Red-black trees are a type of binary search tree that maintain balance through color properties and rotations, ensuring efficient search, insertion, and deletion operations. Each node has a color attribute (red or black) and specific properties that must be upheld, including that no two red nodes can be adjacent. Rotations are necessary to resolve conflicts and maintain the tree's balance, while augmenting data structures can enhance functionality for complex queries.

Uploaded by

aditigzp2005
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Unit II

Red-Black Trees
Red-Black Trees
A red-black tree is a binary search tree with one extra bit of storage per node: its color, which
can be either RED or BLACK. By constraining the node colors on any simple path from the
root to a leaf, red-black trees ensure that no such path is more than twice as long as any other,
so that the tree is approximately balanced. Indeed, as we’re about to see, the height of a red-
black tree with n keys is at most O(lg n)
Each node of the tree now contains the attributes color, key, left, right , and p. If a child or
the parent of a node does not exist, the corresponding pointer attribute of the node contains
the value NIL. Think of these NILs as pointers to leaves (external nodes) of the binary search
tree and the normal, key-bearing nodes as internal nodes of the tree.
A red-black tree is a binary search tree that satisfies the following red-black properties:
1. Every node is either red or black.
2. The root is black.
3. Every leaf (NIL) is black.
4. If a node is red, then both its children are black.
5. For each node, all simple paths from the node to descendant leaves contain the same number of
black nodes.
Figure 13.1(a) shows an example of a red-black tree.
As a matter of convenience in dealing with boundary conditions in red-blacktree code, we use a single
sentinel to represent NIL . For a red-black tree T , the sentinel T:nil is an object with the same
attributes as an ordinary node in the tree. Its color attribute is BLACK, and its other attributes p, left,
right , and key can take on arbitrary values. As Figure 13.1(b) shows, all pointers to NIL are replaced
by pointers to the sentinel T:nil.

Rotations
The search-tree operations TREE-INSERT and TREE-DELETE, when run on a redblack tree with n
keys, take O.lg n/ time. Because they modify the tree, the result may violate the red-black properties
enumerated . To restore theseproperties, colors and pointers within nodes need to change.
The pointer structure changes through rotation, which is a local operation in a search tree that
preserves the binary-search-tree property. Figure 13.2 shows thetwo kinds of rotations: left rotations
and right rotations. Let’s look at a left rotationon a node x, which transforms the structure on the right
side of the ûgure to the structure on the left. Node x has a right child y, which must not be T:nil. The
left rotation changes the subtree originally rooted at x by <twisting= the link between xand y to the
left. The new root of the subtree is node y, with x as y’s left child andy’s original left child (the sub
tree represented by β in the figure) as x’s right child.

The pseudocode for LEFT-ROTATE appearing on the following page assumes That x.right ≠ T.nil
and that the root’s parent is T.nil. Figure 13.3 shows an example of how LEFT-ROTATE modifies a
binary search tree. The code for RIGHTROTATE is symmetric. Both LEFT-ROTATE and RIGHT-
ROTATE run in O(1)time.
Only pointers are changed by a rotation, and all other attributes in a node remain the same.
Why Rotations Are Necessary in Red-Black Trees:
Red-black trees are balanced binary search trees, where balancing ensures the tree does not
become skewed (either too deep on one side). To maintain balance, we need to ensure the
tree's height remains logarithmic in terms of the number of nodes, which guarantees efficient
search, insertion, and deletion operations.
When a red-red conflict occurs (meaning both a node and its parent are red), we sometimes
cannot fix the tree simply by recoloring. Rotations are structural changes to the tree, which
ensure that the red-black tree properties are restored while keeping the tree balanced.
Understanding Rotation Scenarios:
Rotations are needed when:
1. The uncle of the inserted node is black, and the tree's structure is causing imbalance
(a red-red conflict).
2. Rotations are performed to "move" nodes up or down the tree, adjusting their
positions to eliminate violations of the red-black properties.
Let’s go through the types of rotations and their specific purpose in the example you shared.
Case 2: Left Rotation Reason
In Case 2, the key issue is that the newly inserted node zzz (node 7) is the right child of its
parent (node 2), causing an unbalanced structure.
Why Left Rotation is Needed:
 Without the left rotation, node 2 and its child 7 form a "zig-zag" shape. This
unbalanced structure violates the binary search tree properties and could increase the
tree's height unnecessarily, leading to inefficiencies.
 Left rotation is performed to transform this "zig-zag" shape into a more balanced
"straight-line" structure. Specifically, the left rotation "moves" node 7 up, making it
the parent of node 2. After this rotation, the tree is more balanced.
The result is that the inserted node zzz (node 7) becomes the new parent, and the former
parent (node 2) becomes its left child, transforming the unbalanced structure into a more
balanced one.
Case 3: Right Rotation Reason
After the left rotation, there’s still a red-red conflict between node 7 and node 11 (its parent).
Since 7 is the left child of its parent 11, we perform a right rotation.
Why Right Rotation is Needed:
 The red-red conflict between node 7 (red) and its parent 11 (also red) violates the red-
black tree property that no red node can have a red child.
 A right rotation around the grandparent (node 11) is performed to rebalance the tree.
This moves node 7 into a better position in the tree, making it the new root of the
subtree, and moves node 11 down, making it the right child of 7.
This rotation fixes the red-red conflict and restores the balanced tree structure.
Key Reasons for Rotations:
1. Maintain balance: Prevent the tree from becoming too deep (skewed) on one side.
2. Resolve red-red conflicts: When both the parent and child are red, rotations help
eliminate this conflict by repositioning nodes.
3. Keep properties intact: Rotations ensure that all red-black tree properties
(particularly property 4 about red nodes not having red children) are preserved.

Insertion in Red-Black Trees


When a new node is inserted, it is initially colored red to maintain balance. However, this
may violate the Red-Black Tree properties. The tree is then "fixed" by performing a series of
rotations and recoloring.
Steps for insertion:
1. Insert the new node as a red node, similar to a standard binary search tree.
2. If the parent of the inserted node is black, no further adjustments are needed.
3. If the parent is red, this violates the property that red nodes cannot have red children.
Fix this by either recoloring or performing rotations (left or right) to restore balance.
Example of Red-Black Tree Insertion
Consider the following insertion sequence into an initially empty Red-Black Tree:
 Insert 7.
 Insert 3.
 Insert 18.
 Insert 10.
 Insert 22.
 Insert 8.
Steps:
1. Insert 7: Since the tree is empty, 7 becomes the root and is colored black.
markdown
7B
2. Insert 3: It becomes the left child of 7 and is colored red.
markdown
7B
/
3R
3. Insert 18: It becomes the right child of 7 and is colored red. No violations occur
because the parent (7) is black.
markdown
7B
/\
3R 18R
4. Insert 10: 10 is inserted as the left child of 18 and is colored red. Since 18 is red, a
violation occurs. To fix this, a right rotation around 18 is performed, followed by
recoloring.
After fixing:

7B

/ \
3R 18B
/
10R

5. Insert 22: It becomes the right child of 18 and is colored red. No violations occur as
18 is black.
7B
/ \
3R 18B
/ \
10R 22R

6. Insert 8: It becomes the left child of 10 and is colored red. This creates a violation as
both 8 and 10 are red. This is fixed by performing a left rotation on 7 and recoloring.
After the final adjustment:
10B
/ \
7R 18B
/ \ \
3B 8R 22R

Why Red-Black Trees?


 Self-balancing: Keeps the tree balanced without requiring full rebalancing, which
could be expensive.
 Efficient operations: Ensures efficient process management and selection with
predictable worst-case performance.
 Space efficiency: Uses less space compared to AVL trees, making it suitable for
system-level operations where performance is critical.
The CFS, which powers much of Linux’s scheduling logic, depends on the Red-Black Tree to
fairly distribute CPU time among tasks, providing a balanced approach to multitasking.

Augmenting Data Structures:


Introduction to Augmenting Data Structures: Augmenting data structures involve
enhancing an existing data structure by adding extra information or functionalities to
solve more complex problems efficiently. The idea is to modify basic data structures
like trees, heaps, or arrays to support additional operations or answer complex queries
without significantly affecting the performance of existing operations.
Augmenting data structures is a powerful technique that extends the capabilities of
standard data structures like trees, heaps, and arrays. By carefully maintaining
additional information at each node, we can solve more complex problems efficiently
without significantly compromising the performance of standard operations. This
concept is widely used in advanced algorithms and systems where both static and
dynamic queries need to be handled efficiently.

Example: Augmenting a Binary Search Tree (BST)


A simple example of an augmented data structure is a Binary Search Tree (BST)
augmented to support order statistics, such as finding the rank of an element or
selecting the k-th smallest element. This can be done by maintaining an extra field
size in each node, which keeps track of the number of nodes in the subtree rooted at
that node.
Augmentation Process:
1. Basic Structure: Start with a standard BST where each node has a key, left child, and
right child.
2. Augmenting Information: Add an extra field size to each node, where size represents
the total number of nodes in the subtree rooted at that node.
3. Maintaining Augmentation: Update the size field during the insertions and deletions.
For a node n, the value of n.size will be 1 + size(left(n)) + size(right(n)), where left(n)
and right(n) are the left and right children of n.
Operations:
 Rank(x): Find the rank of an element x (i.e., how many elements are smaller than x).
 Select(k): Find the k-th smallest element in the tree.

To represent the augmented Binary Search Tree (BST) discussed earlier, we'll
visualize how we can add the size field to each node in the tree. Here's an example of
a BST augmented with size information, which keeps track of the number of nodes in
each subtree.
Step-by-Step Example
Initial Binary Search Tree (BST):
Let’s consider a basic BST with the following elements inserted in this order: 10, 5, 15, 2, 7,
12, 20.
Step 1: Inserting the Elements
First, insert 10 as the root.
Insert 5 (go left from 10), then insert 15 (go right from 10).
Insert 2 (left from 10, left from 5), insert 7 (left from 10, right from 5).
Insert 12 (right from 10, left from 15), insert 20 (right from 10, right from 15).

The structure will look like this (without augmentation):

10
/ \
5 15
/ \ / \
2 7 12 20
Step 2: Augmenting the Tree with size Field
Now we add the size field to each node. The size of a node will be the total number of nodes
in its subtree (including itself). Here’s how the size will be calculated:
2, 7, 12, 20 are leaf nodes, so their size = 1.
5 has two children (2 and 7), so size (5) = 1 + size (2) + size(7) = 1 + 1 + 1 = 3.
15 has two children (12 and 20), so size (15) = 1 + size (12) + size(20) = 1 + 1 + 1 =
3.
10 has two children (5 and 15), so size (10) = 1 + size (5) + size(15) = 1 + 3 + 3 = 7.
Step 3: Tree Representation with Size Field
The tree now looks like this, with each node showing the key(size):

10(7)

/ \
5(3) 15(3)

/ \ / \
2(1) 7(1) 12(1) 20(1)
Each node has been augmented with the size of the subtree rooted at that node.

Order-statistic tree
An order-statistic tree T is simply a red-black tree with additional information stored in each node.
Each node x contains the usual red-black tree attributes x.key, x.color, xp, x.left, and x.right , along
with a new attribute, x.size. This attribute contains the number of internal nodes in the subtree rooted
at x (including x itself, but not including any sentinels), that is, the size of the subtree. If we define the
sentinel’s size to be 0 that is, we set T.nil.size to be 0 - then we have the identity
x.size = x.left.size + x.right.size + 1

OS-RANK.T; x/
1 r = x.left:size + 1 // rank of x within the subtree rooted at x
2 y=x // root of subtree being examined
3 while y ≠ T.root
4 if y == y.p.right // if root of a right subtree . . .
5 r = r+ y.p left.size +1 // . . . add in parent and its left subtree
6 y = y.p // move y toward the root
7 return r
B-Trees
B-trees are balanced search trees designed to work well on disk drives or other direct-access
secondary storage devices. B-trees are similar to red-black trees, but they are better at minimizing the
number of operations that access disks. (We often say just”disk” instead of disk drivers “) Many
database systems use B-trees, or variants of B-trees, to store information.
. A simple B-tree is shown in the figure given below

A B-tree is a type of self-balancing search tree commonly used in databases and file systems.
The base properties of a B-tree include:
2 B TREES
A B tree is a specialized M-way tree that is widely used for disk access. A B tree of order m
can have a maximum of m–1 keys and m pointers to its sub-trees. A B tree may contain a
large number of key values and pointers to sub-trees. Storing a large number of keys in a
single node keeps the height of the tree relatively small.
A B tree is designed to store sorted data and allows search, insertion, and deletion operations
to be performed in logarithmic repaid time. A B tree of order m (the maximum number of
children that each node can have) is a tree with all the properties of an M-way search tree. In
addition it has the following properties:
1. Every node in the B tree has at most (maximum) m children.
2. Every node in the B tree except the root node and leaf nodes has at least (minimum)
m/2 children. This condition helps to keep the tree bushy so that the path from the
root node to the leaf is very short, even in a tree that stores a lot of data.
3. The root node has at least two children if it is not a terminal (leaf) node.
4. All leaf nodes are at the same level.
An internal node in the B tree can have n number of children, where 0<= n<= m. It is not
necessary that every node has the same number of children, but the only restriction is that the
node should have at least m/2 children. As B tree of order 4 is given in Fig.

Inserting a New Element in a B Tree


In a B tree, all insertions are done at the leaf node level. A new value is inserted in the B tree
using the algorithm given below.
1. Search the B tree to find the leaf node where the new key value should be inserted.
2. If the leaf node is not full, that is, it contains less than m–1 key values, then insert
the new
element in the node keeping the node’s elements ordered.
3. If the leaf node is full, that is, the leaf node already contains m–1 key values, then
(a) insert the new value in order into the existing set of keys,
(b) split the node at its median into two nodes (note that the split nodes are
half full), and
(c) push the median element up to its parent’s node. If the parent’s node is
already full, then split the parent node by following the same steps

Till now, we have easily inserted 8 and 9 in the tree because the leaf nodes were not
full. But now, the node in which 39 should be inserted is already full as it contains
four values. Here we split the nodes to form two separate nodes. But before
splitting, arrange the key values in order (including the new value). The ordered set
of values is given as 21, 27, 36, 39, and 42. The median value is 36, so push 36 into
its parent’s node and split the leaf nodes.

Now the node in which 4 should be inserted is already full as it contains four key
values. Here we split the nodes to form two separate nodes. But before splitting, we
arrange the key values in order (including the new value). The ordered set of values
is given as 4, 7, 8, 9, and 11. The median value is 8, so we push 8 into its parent’s
node and split the leaf nodes. But again, we see that the parent’s node is already
full, so we split the parent node using the same procedure.

Like insertion, deletion is also done from the leaf nodes. There are two cases of
deletion. In the first case, a leaf node has to be deleted. In the second case, an
internal node has to be deleted. Let us first see the steps involved in deleting a leaf
node.
1. Locate the leaf node which has to be deleted.
2. If the leaf node contains more than the minimum number of key values
(more than m/2 elements), then delete the value.
3. Else if the leaf node does not contain m/2 elements, then fill the node by
taking an element either from the left or from the right sibling.
(a) If the left sibling has more than the minimum number of key
values, push its largest key into its parent’s node and pull down the
intervening element from the parent node to the leaf node where
the key is deleted.
(b) Else, if the right sibling has more than the minimum number of
key values, push its smallest key into its parent node and pull down
the intervening element from the parent node to the leaf node
where the key is deleted.
4. Else, if both left and right siblings contain only the minimum number of
elements, then create a new leaf node by combining the two leaf nodes and
the intervening element of the parent node (ensuring that the number of
elements does not exceed the maximum number of elements a node can
have, that is, m). If pulling the intervening element from the parent node
leaves it with less than the minimum number of keys in the node, then
propagate the process upwards, thereby reducing the height of the B tree
To delete an internal node, promote the successor or predecessor of the key to be deleted
to occupy the position of the deleted key. This predecessor or successor will always be in the
leaf node. So the processing will be done as if a value from the leaf node has been deleted
Binomial Heap
A Binomial Heap is a specialized form of heap (priority queue) that comprises a collection of
heap-ordered trees, specifically binomial trees. The utility of binomial heaps lies in their
ability to efficiently perform various heap operations, including insertion, merging, locating
the minimum element, and deletion.

1. Binomial Tree
A binomial tree is a recursive data structure characterized as follows:

A binomial tree of order k (denoted as B_k) consists of a root node and k subtrees,
where each subtree is a binomial tree of order k−1. The arrangement is such that the i-
th subtree corresponds to a binomial tree of order i. The total number of nodes in a
binomial tree of order k is 2^k, and its height is k.
Example:
B_0: A single node.
B_1: Two nodes, with one serving as the root and the other as its child.
B_2: A binomial tree comprising 4 nodes: root → one child (which has two children).
Binomial trees are advantageous due to their efficient support for merge operations.

2. Structure of a Binomial Heap


A binomial heap is a collection of binomial trees that adhere to two fundamental
properties:

Min-Heap Property: The key of the parent node is always less than or equal to the
keys of its children.
Order Property: A binomial heap containing n nodes consists of at most one binomial
tree of each order, represented as a collection of binomial trees B_0, B_1, …, B_k,
where k is the highest order such that 2^k ≤ n.
For instance, a binomial heap with 13 nodes can be represented using the binomial
trees B_0, B_2, B_3 (since 13 = 1 + 4 + 8 = 2^0 + 2^2 + 2^3).

Example of Binomial Heap

Let’s start with a binomial heap consisting of the following three binomial trees:

 B0B_0B0 (1 node) with root 10.


 B1B_1B1 (3 nodes) with root 15 and children 25 and 30.
 B2B_2B2 (7 nodes) with root 5, and its children: 12, 20, 35, 40, 50, 45.

B0 (1 node) B1 (3 nodes) B2 (7 nodes)


10 15 5
/ \ / | \
25 30 12 20 35
/\ /\
40 50 45

You might also like