Design of Algorithms Assignment
Design of Algorithms Assignment
1)Red-Black Tree
a)Inserting an element into a Red-Black Tree
While inserting a new node, the new node is always inserted as a RED node. After insertion of a new
node, if the tree is violating the properties of the red-black tree then, we do the following
operations.
1. Recolour
2. Rotation
0. If the color of the left child of gP of z is RED, set the color of both the children
of gP as BLACK and the color of gP as RED.
a. Assign gP to newNode.
b. Else if newNode is the left child of p then, assign p to newNode and Right-
Rotate newNode.
c. Set color of p as BLACK and color of gP as RED.
d. Left-Rotate gP.
4. Set the root of the tree as BLACK.
This operation removes a node from the tree. After deleting a node, the red-black property
is maintained again.
class RedBlackTree():
def __init__(self):
self.TNULL = Node(0)
self.TNULL.color = 0
self.TNULL.left = None
self.TNULL.right = None
self.root = self.TNULL
# Preorder
def pre_order_helper(self, node):
if node != TNULL:
sys.stdout.write(node.item + " ")
self.pre_order_helper(node.left)
self.pre_order_helper(node.right)
# Inorder
def in_order_helper(self, node):
if node != TNULL:
self.in_order_helper(node.left)
sys.stdout.write(node.item + " ")
self.in_order_helper(node.right)
# Postorder
def post_order_helper(self, node):
if node != TNULL:
self.post_order_helper(node.left)
self.post_order_helper(node.right)
sys.stdout.write(node.item + " ")
s.color = x.parent.color
x.parent.color = 0
s.left.color = 0
self.right_rotate(x.parent)
x = self.root
x.color = 0
# Node deletion
def delete_node_helper(self, node, key):
z = self.TNULL
while node != self.TNULL:
if node.item == key:
z = node
y=z
y_original_color = y.color
if z.left == self.TNULL:
x = z.right
self.__rb_transplant(z, z.right)
elif (z.right == self.TNULL):
x = z.left
self.__rb_transplant(z, z.left)
else:
y = self.minimum(z.right)
y_original_color = y.color
x = y.right
if y.parent == z:
x.parent = y
else:
self.__rb_transplant(y, y.right)
y.right = z.right
y.right.parent = y
self.__rb_transplant(z, y)
y.left = z.left
y.left.parent = y
y.color = z.color
if y_original_color == 0:
self.delete_fix(x)
def preorder(self):
self.pre_order_helper(self.root)
def inorder(self):
self.in_order_helper(self.root)
def postorder(self):
self.post_order_helper(self.root)
y = x.parent
while y != self.TNULL and x == y.right:
x=y
y = y.parent
return y
y = x.parent
while y != self.TNULL and x == y.left:
x=y
y = y.parent
return y
y.parent = x.parent
if x.parent == None:
self.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y
y.parent = x.parent
if x.parent == None:
self.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y
y = None
x = self.root
while x != self.TNULL:
y=x
if node.item < x.item:
x = x.left
else:
x = x.right
node.parent = y
if y == None:
self.root = node
elif node.item < y.item:
y.left = node
else:
y.right = node
if node.parent == None:
node.color = 0
return
if node.parent.parent == None:
return
self.fix_insert(node)
def get_root(self):
return self.root
def print_tree(self):
self.__print_helper(self.root, "", True)
if __name__ == "__main__":
bst = RedBlackTree()
bst.insert(55)
bst.insert(40)
bst.insert(65)
bst.insert(60)
bst.insert(75)
bst.insert(57)
bst.print_tree()
degree[x] = 0
p[x] = NIL
child[x] = NIL
left[x] = x
right[x] = x
mark[x] = FALSE
then min[H] = x
n[H] = n[H] + 1
3. If the heap is empty, set the new node as a root node and mark it min.
4. Else, insert the node into the root list and update min.
Union
Extract Min
3. Create an array of size equal to the maximum degree of the trees in the heap before
deletion.
4. Do the following (steps 5-7) until there are no multiple roots with the same degree.
5. Map the degree of current root (min-pointer) to the degree in the array.
7. If there are more than two mappings for the same degree, then apply union operation to
those roots such that the min-heap property is maintained (i.e. the minimum is at the root).
import math
# Insert a node
def insert_node(self, value):
new_tree = FibonacciTree(value)
self.trees.append(new_tree)
if (self.least is None or value < self.least.value):
self.least = new_tree
self.count = self.count + 1
self.least = None
for k in aux:
if k is not None:
self.trees.append(k)
if (self.least is None
or k.value < self.least.value):
self.least = k
def floor_log(x):
return math.frexp(x)[1] - 1
fibonacci_heap = FibonacciHeap()
fibonacci_heap.insert_node(7)
fibonacci_heap.insert_node(3)
fibonacci_heap.insert_node(17)
fibonacci_heap.insert_node(24)
3)Heap Sort
2.At this point, the largest item is stored at the root of the heap. Replace it with the last item of the
heap followed by reducing the size of heap by 1. Finally, heapify the root of the tree.
largest = l
largest = r
if largest != i:
heapify(arr, n, largest)
def heapSort(arr):
n = len(arr)
heapify(arr, n, i)
heapify(arr, i, 0)
# Driver code
heapSort(arr)
n = len(arr)
for i in range(n):