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

Data Structure-tree

zxsder

Uploaded by

PK Ki Vines
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

Data Structure-tree

zxsder

Uploaded by

PK Ki Vines
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

Data Structure

Dr. Deebha Mumtaz


Queue
● A queue is a linear data structure that follows the First In First Out (FIFO) order of insertion and deletion, i.e. the element
that is inserted first will be the first one to be removed and the element that is inserted last will be removed at last.
● It can be constructed with an array or a linked list.
Queue
Applications
○ They are used in they are useful for implementing algorithms that require elements to be processed in a precise sequence, such
as breadth-first search and task scheduling.
○ They are used in web servers to schedule incoming requests.
○ They are used in Buffering I/O systems, Print spooling, CPU scheduling
○ Handling of interrupts in real-time systems.
○ Because queue operations have an O(1) time complexity, they can be executed fast even on enormous queues.

Disadvantages
○ A queue, unlike a stack, cannot be constructed with a single pointer, making queue implementation slightly more involved.
○ If the queue is constructed as an array, it might soon fill up if too many elements are added, resulting in performance concerns
or possibly a crash.
○ When utilising a linked list to implement the queue, the memory overhead of each node can be significant, especially for small
elements.
Operations in Queue
○ Basic queue operations:
a. Enqueue add an element to the back/rear pointer
b. Dequeue remove an element from the front pointer
c. Peek: Returns the front element of the queue.
d. IsFull: Returns true is the queue is full otherwise returns false.
e. IsEmpty: Returns true is the queue is empty otherwise returns false.
Types of Queue

Priority Queue: Each element is assigned a particular priority


value and elements in the queue are aligned based on priority.

Circular Queue/ Ring Buffer: the last position is linked


back to the first position, forming a circular arrangement.

Double-ended Queue/ Deque: Enqueue (insertion) and


dequeue (deletion) operations are performed at both ends,
i.e., the rear-end (tail) and the front-end (head).
Array Implementation of Queue - EnQueue
Approach:Keep track of two variables Front and Rear

Step 1: Check if the Queue is Empty,

IF FRONT = -1 and REAR = -1


SET FRONT = REAR = 0

Step 2: Check whether the Queue is Full

IF REAR = MAX - 1
Write OVERFLOW

Step 3: Else If the Queue is Not Empty, Increment the


rear pointer.

SET REAR = REAR + 1

Step 4: Add the data at the Rear position of Array

Set QUEUE[REAR] = NUM


Array Implementation of Queue-DeQueue
Step 1: Check whether the queue is empty.

IF FRONT = -1 or FRONT > REAR


Write UNDERFLOW

Step 2: If the queue is not empty, Increment the front


pointer of the queue. Remove the element at the front
position.

SET VAL = QUEUE[FRONT]


SET FRONT = FRONT + 1
Array Implementation of Queue
#define MAX_SIZE 100
int dequeue() { int main() {
if (front == -1 || front > rear) { enqueue(10);
int queue[MAX_SIZE];
printf("Queue is empty"); enqueue(20);
int front = -1;
return -1; enqueue(30);
int rear = -1;
} printf("%d ", dequeue());
int element = queue[front]; printf("%d ", dequeue());
void enqueue(int element)
front++; printf("%d ", dequeue());
{
return element; printf("%d ", dequeue());
if (rear == MAX_SIZE - 1) {
} return 0;
printf("Queue is full");
}
return;
}
if (front == -1) {
front = 0;
}
rear++;
queue[rear] = element;
}
Array Implementation of Queue - Peek

● Step 1: Check if the queue is empty.


● Step 2: If the queue is empty, return -1.
● Step 3: If not, return QUEUE[FRONT + 1].
Drawback of Array Implementation of Queue
1. Memory wastage : The space of the array, which is used to store queue elements, can never be reused to store
the elements of that queue because the elements can only be inserted at front end and the value of front might be
so high so that, all the space before that, can never be filled.
2. Deciding the array size: Array implementation is the size of the array which requires to be declared in advance.
Due to this reason, we can declare the array large enough so that we can store queue elements as enough as
possible but the main problem with this declaration is that, most of the array slots (nearly half) can never be
reused. It will again lead to memory wastage.
Linked List implementation of Queue
Advantages:
1. Nodes are allocated dynamically, so the queue can grow and shrink as much as needed.
2. Overflow is not possible until and unless the heap memory got exhausted.

Approach: Maintain two pointers, front, and rear. The front points to the first item of the queue and rear points to the last item.

Operations:
1. EnQueue(): This operation adds a new node after the rear and moves the rear to the next node.
2. DeQueue(): This operation removes the front node and moves the front to the next node.
Linked List implementation of Queue- Enqueue
1. Create a new node with the given data. struct Node {
2. If the queue is empty, set the front and rear to the new node.
int data;
3. Else, set the next of the rear to the new node and update the rear.
struct Node* next;

};
Linked List implementation of Queue- DeQueue
● Check if the queue is empty.
● If not empty, store the front node in a temporary variable.
● If the queue has only one element, update pointers to
NULL
● Else Update the front pointer to the next node.
● Free the temporary node.
Circular Queue
● A Circular Queue is an extended version of a normal queue where the last element of
the queue is connected to the first element of the queue forming a circle.

● The operations are performed based on FIFO (First In First Out) principle. It is also
called ‘Ring Buffer’.

● Two variables used:


○ Front: Point to the front item from the queue.
○ Rear: Point to the last item from the queue.

● Applications of Circular Queue:


1. Memory Management: The unused memory locations in the case of ordinary
queues can be utilized in circular queues.
2. Traffic system: In computer controlled traffic system, circular queues are used to
switch on the traffic lights one by one repeatedly as per the time set.
3. CPU Scheduling: Operating systems often maintain a queue of processes that are
ready to execute or that are waiting for a particular event to occur.
Operations on Circular Queue
1. enQueue(value) This function is used to insert an element into the circular queue. In a circular queue, the new element is always
inserted at the rear position.
2. deQueue() This function is used to delete an element from the circular queue. In a circular queue, the element is always deleted
from the front position.
Array Implementation of EnQueue

Step 1: Check if the queue is Full


IF (REAR+1)%MAX = FRONT
Write " OVERFLOW "
Goto step 4
Step 2: Check if the queue is Empty
IF FRONT = -1 and REAR = -1 (Empty)
SET FRONT = REAR = 0 i.e. set the variables to first location

ELSE IF REAR = MAX - 1 and FRONT ! = 0 (i.e. rear is filled and front portion is available)
SET REAR = 0 (point to first location)

ELSE
SET REAR = (REAR + 1) % MAX
[END OF IF]

Step 3: SET QUEUE[REAR] = VAL

Step 4: EXIT
Array Implementation of DeQueue
Step 1: Check if the queue is Empty
IF FRONT = -1
Write " UNDERFLOW "
Goto Step 4

Step 2: SET VAL = QUEUE[FRONT]


Step 3: IF FRONT = REAR (there is only one element in queue)
SET FRONT = REAR = -1
ELSE
IF FRONT = MAX -1
SET FRONT = 0
ELSE
SET FRONT = FRONT + 1
[END of IF]
[END OF IF]
Step 4: EXIT
Linked List Implementation of EnQueue
1. First, allocate the memory for a new node
2. Check if the queue is Empty
if(rear == -1)
{ front = rear = newnode;
Rear->next = front
}
else
{ rear->next=newnode;
rear=newnode;
rear->next=front;
}
Linked List Implementation of DeQueue
1. Allocate value of front to a variable
struct node *temp;
temp=front;
2. Check if the Queue is Empty
if((front==-1)&&(rear==-1))
{ printf("\nQueue is empty");
}
else if(front==rear) (Only one element is present, set both the front and the rear pointer to NULL.)
{
front=rear= -1;
free(temp);
}
else (Update the front variable and repoint rear variable)
{
front=front->next;
rear->next=front;
free(temp);
}
Deque (or double-ended queue)
Deque is a linear data structure where the insertion and deletion operations are performed from both ends.

Types of deque

In input restricted queue, insertion operation can be In output restricted queue, deletion operation can be
performed at only one end, while deletion can be performed at only one end, while insertion can be
performed from both ends.
performed from both ends.
Operations performed on Deque
○ Insertion at front
○ Insertion at rear
○ Deletion at front
○ Deletion at rear

Before performing these operations, we must follow the below two steps:

1. Declare an array(to be used as a deque) of size N.


2. Set two pointers at first position i.e. front = -1 and rear = 0

Dequeue can be implemented by:

1. In a circular array, if the array is full, we start from the beginning.


2. In a linear array implementation, if the array is full, no more elements can be inserted.
1. Insertion at Front in Deque
1. Check if the deque is full. i.e. (front == 0 && rear
== n - 1) || (front == rear + 1). Insertion operation
cannot be performed (overflow condition).
2. If the deque is empty, reinitialize front = 0. And, add
the new key into array[front].
3. If front = 0, reinitialize front = n-1 (last index).
4. Else, decrease front by 1.
5. Add the new key into array[front].
2. Insert at the Rear
This operation adds an element to the rear.

1. Check if the deque is full. If the deque is full, insertion operation

cannot be performed (overflow condition).

2. If the deque is empty, reinitialize rear = 0. And, add the new key into

array[rear].

3. If rear = n - 1, reinitialize rear = 0 (first index).

4. Else, increase rear by 1.

5. Add the new key into array[rear].


3. Delete from the Front
1. Check if the deque is empty. If the deque is empty
deletion cannot be performed (underflow condition).

2. If the deque has only one element (i.e. front = rear), set
front = -1 and rear = -1.
3. Else if front is at the last index (i.e. front = n - 1), set
front = 0.
4. Else, front = front + 1.
4. Delete from the Rear
1. Check if the deque is empty.

If the deque is empty (i.e. front = -1), deletion cannot be

performed (underflow condition).

2. If the deque has only one element (i.e. front = rear), set

front = -1 and rear = -1, else follow the steps below.

3. If rear is at the first index (i.e. rear = 0), reinitialize rear =

n - 1.

4. Else, rear = rear - 1


TREE DATA STRUCTURE
● Tree data structure is a non-linear, hierarchical structure that is
used to represent and organize data in a way that is easy to
navigate and search.
● It is a collection of nodes that are connected by edges and has a
hierarchical relationship between the nodes.
● The topmost node of the tree is called the root, and the nodes
below it are called the child nodes.
● Each node can have multiple child nodes, and these child nodes
can also have their own child nodes, forming a recursive
structure.
TREE DATA STRUCTURE
● Uses of Tree data structure:
a. Hierarchical Data: File systems, organizational models, etc.
b. Routing Tables: Used for routing data in network algorithms.
c. Sorting/Searching: Used for sorting data and searching for data.
d. Priority Queues: Priority queue data structures are commonly implemented using trees, such as binary heaps.
e. Data Compression: Huffman coding is a popular technique for data compression that involves constructing a binary
tree.
f. Compiler Design: In compiler design, a syntax tree is used to represent the structure of a program.
g. Database Indexing: B-trees and other tree structures are used in database indexing to efficiently search for and retrieve
data.
● Disadvantages of Tree Data Structure:
a. Unbalanced Trees, meaning that the height of the tree is skewed towards one side, which can lead to inefficient search
times.
b. Trees demand more memory space requirements than some other data structures like arrays and linked lists, especially if
the tree is very large.
c. The implementation and manipulation of trees can be complex and require a good understanding of the algorithms.
Basic Terminologies In Tree Data Structure:
Parent Node: The node which is a predecessor of a node is called the parent node
of that node.

Child Node: The node which is the immediate successor of a node is called the
child node of that node.

Root Node: The topmost node of a tree or the node which does not have any parent
node is called the root node. A non-empty tree must contain exactly one root node
and exactly one path from the root to all other nodes of the tree.

Leaf Node or External Node: The nodes which do not have any child nodes are
called leaf nodes.

Ancestor of a Node: Any predecessor nodes on the path of the root to that node
are called Ancestors of that node. {A,B} are the ancestor nodes of the node {E}

Descendant: A node x is a descendant of another node y if and only if y is an


ancestor of x.
Basic Terminologies In Tree Data Structure:

Sibling: Children of the same parent node are called siblings. {D,E} are called
siblings.

Level of a node: The count of edges on the path from the root node to that node.
The root node has level 0.

Internal node: A node with at least one child is called Internal Node.

Neighbour of a Node: Parent or child nodes of that node are called neighbors of
that node.

Subtree: Any node of the tree along with its descendant.


Properties of Tree Data Structure:
Number of edges: An edge can be defined as the connection between two
nodes. If a tree has N nodes then it will have (N-1) edges. There is only one
path from each node to any other node of the tree.

Depth of a node: The depth of a node is defined as the length of the path
from the root to that node. Each edge adds 1 unit of length to the path. So,
it can also be defined as the number of edges in the path from the root of
the tree to the node.

Height of the Tree: The height of a tree is the length of the longest path
from the root of the tree to a leaf node of the tree.
Types of Trees
● Binary Trees: Each node has up to two children, the left child node and the right child node. This structure is the foundation for more
complex tree types like Binary Search Trees and AVL Trees.
● Ternary Tree: A Ternary Tree is a tree data structure in which each node has at most three child nodes, usually distinguished as “left”,
“mid” and “right”.
● N-ary Tree or Generic Tree: Generic trees are a collection of nodes where each node is a data structure that consists of records and a
list of references to its children. Unlike the linked list, each node stores the address of multiple nodes.
Binary Tree
Binary tree is a tree data structure(non-linear) in which each node can have at most
two children which are referred to as the left child and the right child.
struct node
{
int data;
struct node *left;
struct node *right;
}
Types of Binary Tree

Perfect Binary Tree: All the internal nodes have two children and Skewed Binary Tree: the tree is either dominated by the left nodes or the
all leaf nodes are at the same level.
right nodes

Complete Binary Tree: all the levels are completely filled except
Full Binary Tree: Each node has either zero children or two possibly the last level and the last level has all keys as left as
children. possible.
Binary Tree Implementation
#include <stdio.h>
int main() {
#include <stdlib.h>
// Initialize and allocate memory for tree nodes
struct Node* firstNode = createNode(2);
struct Node {
struct Node* secondNode = createNode(3);
int data;
struct Node* thirdNode = createNode(4);
struct Node *left;
struct Node* fourthNode = createNode(5);
struct Node *right;
};
// Connect binary tree nodes
firstNode->left = secondNode;
struct Node* createNode(int d)
firstNode->right = thirdNode;
{
secondNode->left = fourthNode;
struct Node* newNode =
(struct Node*)malloc(sizeof(struct Node));
return 0;
newNode->data = d;
}
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
Operations On Binary Tree
● Create a Binary Tree
● Traversal in Binary Tree
● Insertion in Binary Tree
● Searching in Binary Tree
● Deletion in Binary Tree
Traversal in Binary Tree
1. Depth-First Search (DFS) algorithms: It explores as far down a branch as possible before backtracking. It is implemented using
recursion.
1. Preorder Traversal (root-left-right): Visits the node first, then left subtree, then right subtree.
2. Inorder Traversal (left-root-right): Visits left subtree, then the node, then the right subtree.
3. Postorder Traversal (left-right-root): Visits left subtree, then right subtree, then the node.

2. Breadth-First Search (BFS) algorithms: BFS explores all nodes at the present depth before moving on to nodes at the next
depth level. It is typically implemented using a queue.
Traversal in Binary Tree- Depth First Search
1. Preorder traversal is defined as a type of tree traversal that follows the Root-Left-Right policy:
● The root node of the subtree is visited first.
● Then the left subtree is traversed.
● At last, the right subtree is traversed.

OUTPUT: ABC Output: ABDEC


Traversal in Binary Tree
Traversal in Binary Tree
2. Inorder traversal is defined as a type of tree traversal technique which follows the Left-Root-Right pattern, such that:
● The left subtree is traversed first
● Then the root node for that subtree is traversed
● Finally, the right subtree is traversed

Used in BST (Binary Search Tree), if any time there is a need to get the nodes in increasing order

Output: BAC Output: DBEAC


Traversal in Binary Tree
Traversal in Binary Tree
3. Postorder traversal is defined as a type of tree traversal which follows the Left-Right-Root policy such that for each node:

● The left subtree is traversed first


● Then the right subtree is traversed
● Finally, the root node of the subtree is traversed

Uses: 1. This is used for tree deletion because we need to delete subtrees before deleting the current node.

2. It is also useful to get the postfix expression from an expression tree.

Output: BCA Output: DEBCA


Traversal in Binary Tree
Level Order Traversal/ Breadth First Search

● All nodes present in the same level are traversed completely before traversing the next level.
● A lot of popular graph algorithms like Dijkstra’s shortest path, Kahn’s Algorithm, and Prim’s algorithm are based on BFS.
● It can be implemented using queue

Output:
1,2,3,4,5
Representation of binary trees

1. Linked List
2. Array
Array representation of binary trees

Perfect Binary Tree


Array representation of binary trees

To represent any type of binary tree, we


can consider explicitly writing out all
None values in the level-order traversal
sequence.
Array representation of binary trees

Complete binary trees are very suitable for array representation, since all the levels are completely filled except possibly the
last level and the last level has all keys as left as possible.
Array representation of binary trees
Advantages

● Arrays are stored in contiguous memory spaces, which is cache-friendly and allows for faster access and traversal.
● It does not require storing pointers, which saves space.
● It allows random access to nodes.

Limitations

● Array storage requires contiguous memory space, so it is not suitable for storing trees with a large amount of data.
● Adding or deleting nodes requires array insertion and deletion operations, which are less efficient.
● When there are many None values in the binary tree, the proportion of node data contained in the array is low, leading to lower
space utilization.
Binary Search Tree
● All nodes of the left subtree are less than the root node and nodes of the right subtree are
struct node {
greater than the root node. int data;
● The In-order traversal of binary search trees gives the values in ascending order. struct node *right_child;
struct node *left_child;
● All the subtrees of BST hold the same properties.
};
● Because the items are maintained in sorted order in a binary search tree, searching becomes
easier.
Operations on BST C

● Search in BST
● Insertion in BST
● Deletion in BST
Search in BST
Search in BST
1. Check if the tree is empty
If Root == NULL
Return NULL;
2. If the data of the Root matches the target number
number == Root->data
Return Root->data;
3. If the target is greater than the key of the current root, recursively call search function with the right subtree of the current root
and the target.
If number > root->data
Return search(root->right)
4. Else if the target is smaller than the key of the current root, recursively call search function with th left subtree of the current root
and the target.
If number < root->data
Return search(root->left)
5. Return NULL if the target isn't present throughout the entire tree.
Insertion in BST
In a binary search tree, the insertion operation is always carried out at the leaf node.

1. If the current node is NULL, Return a new node created with the specified value.
if node == NULL
return createNode(data)

2. If the value is less than the key of the current node, Recursively call insertNode with the left subtree of the current node and
the value.
if (data < node -> data)
node -> left = insertNode(node -> left, data)

3. If the value is greater than the key of the current node, Recursively call insertNode with the right subtree of the current node
and the value.
else if (data > node -> data)
node -> right = insertNode(node -> right, data)

4. Return the current node


Insertion in BST
Deletion Operation in BST
There are various cases for Deletion of a node:

1. Deleted node is the leaf node:


if (root->left_child == NULL && root->right_child == NULL)
free(root);
return NULL;
Deletion Operation in BST
2. Deleted node has a single child node: In this case, replace the target node with its child (single child) and then delete that child node.
Deletion Operation in BST
3. Deleted node has two children: In this case, at first, we will find the inorder successor of that node. And then replace the node with
the inorder successor. Then remove the inorder successor from its original position.

55
Deletion Operation in BST
Deletion Operation in BST
AVL Tree Data Structure
● AVL Tree is invented by GM Adelson - Velsky and EM Landis in 1962. The difference between the heights of the left subtree
and the right subtree for any node is known as the balance factor of the node.
● BALANCE FACTOR = HEIGHT(LEFT SUBTREE) − HEIGHT(RIGHT SUBTREE)
● An AVL tree defined as a self-balancing Binary Search Tree where the difference between heights of left and right subtrees for
any node cannot be more than one. (-1 ,0,1)
● The time taken for all operations in a binary search tree of height h is O(h). However, it can be extended to O(n) if the BST
becomes skewed (i.e. worst case). By limiting this height to log n, AVL tree imposes an upper bound on each operation to be
O(log n) where n is the number of nodes.

Binary Search Tree AVL tree


Time complexity of AVL
The number of nodes on each level in such an AVL Tree are:

1,2,4,8,16,32,

Which is the same as:.

To get the number of nodes n in a perfect Binary Tree with height


h=3, we can add the number of nodes on each level together:

So in general
AVL Tree Data Structure
Operations on an AVL Tree
● Searching
● Traversing
● Insertion
● Deletion

Searching and traversing do not lead to the violation in property of AVL tree.
However, insertion and deletion are the operations which can violate this property and therefore,the tree can be balanced by applying
rotations.
AVL Rotations
1. Single Rotations
a. Left Rotation (RR Rotation)
b. Right Rotation (LL Rotation)
2. Double Rotations
a. Left-Right Rotation (LR Rotation)
b. Right-Left Rotation (RL Rotation)
AVL Rotations: Left Rotation

1. Left Rotation (RR Rotation): Applied when a node is inserted into the right subtree of the right child.
AVL Rotations: Right Rotation
2. Right Rotation (LL Rotation): Applied when a node is inserted into the left subtree of the left child.
AVL Rotations: Left-Right Rotation

3. Left-Right Rotation (LR Rotation): Applied when a node is inserted into the right subtree of the left child.
AVL Rotations- Right-Left Rotation
4. Right-Left Rotation (RL Rotation): Applied when a node is inserted into the left subtree of the right child.
Insertion: Construct an AVL tree having the following elements: H, I, J, B, A, E, C, F, D

1. Insert: H, I, J 2. Insert: B, A

3. Insert E
4. Insert C, F, D
AVL Delete Node
1. Deletion of a leaf node − If the node to be deleted is a leaf node, then it is deleted without any replacement as it does not
disturb the binary search tree property. However, the balance factor may get disturbed, so rotations are applied to restore it.
2. Deletion of a node with one child − If the node to be deleted has one child, replace the value in that node with the value in its
child node. Then delete the child node. If the balance factor is disturbed, rotations are applied.
3. Deletion of a node with two child nodes − If the node to be deleted has two child nodes, replace its value with the inorder
successor value. If the balance factor exceeds 1 after deletion, apply balance algorithms.
AVL Delete Node
1. Delete: 7 (Leaf Node) 2. Delete: 6 (Node with one child)

3. Delete: 2 (Node with two children) 4. Delete: 5 (no child, imbalance) Apply LL rotation
AVL Tree Data Structure
Advantages of AVL Tree:

1. AVL trees can self-balance themselves and therefore provides time complexity as O(Log n) for search, insert and delete.
2. Since it is a BST , so items can be traversed in sorted order.
3. AVL tree is relatively faster, less complex to understand and implement compared to Red Black Trees.

Disadvantages of AVL Tree:

1. It is difficult to implement compared to normal BST and easier compared to Red Black
2. Due to its rather strict balance, AVL trees provide complicated insertion and removal operations as more rotations are
performed.
B Tree
B-trees/ Balanced Tree are a type of self-balancing tree data structure that maintains sorted data and allows for efficient insertion, deletion,
and search operations.

The B-tree is a data structure that is similar to a binary search tree, but allows multiple keys per node

B trees are specialized in m-way searching, since the order of B trees is 'm'. Order of a tree is defined as the maximum number of children a
node can accommodate. Therefore, the height of a b tree is relatively smaller than the height of AVL tree and RB tree.

The various properties of B trees include −

● Every node in a B Tree will hold a maximum of m children and (m-1) keys, since the order of the tree is m.
● Every node in a B tree, except root and leaf, can hold at least m/2 children
● The root node must have no less than two children.
● All the leaf nodes must be at the same level.
● A B tree always maintains sorted data.

B-Tree of minimum order 5


Insert Operation in B-Tree
The insertion operation for a B Tree is done similar to the Binary Search Tree but the elements are
inserted into the same node until the maximum keys are reached.
Insert Operation in B-Tree
Insert Operation in B-Tree
Delete Operation in B-Tree
Deletion in a B-Tree can be classified into two cases:
1. Deletion from the leaf node.
2. Deletion from the non-leaf node.

1. Case 1a: If there are more than m/2 keys in the leaf node then delete the desired key from the node.
2. Case 1b:If the leaf node doesn't contain m/2 keys then complete the keys by taking the element from right or left sibling.
a. If the left sibling contains more than m/2 elements then push its largest element up to its parent and move the intervening element
down to the node where the key is deleted.
b. If the right sibling contains more than m/2 elements then push its smallest element up to the parent and move intervening element
down to the node where the key is deleted.
3. Case 1c:If neither of the sibling contain more than m/2 elements then create a new leaf node by joining two leaf nodes and the intervening
element of the parent node.
4. Case 2: In this case, the height of the tree shrinks. If the target key lies in an internal node, and the deletion of the key leads to a fewer
number of keys in the node (i.e. less than the minimum required), then look for the inorder predecessor and the inorder successor. If both the
children contain a minimum number of keys then, borrowing cannot take place. This leads to merging the children. Again, look for the
sibling to borrow a key. But, if the sibling also has only a minimum number of keys then, merge the node with the sibling along with the
parent. Arrange the children accordingly (increasing order).
Case 1a − If the key to be deleted is in a leaf node and the deletion does not violate the minimum key
property, just delete the node.
Case 1b: If the key to be deleted is in a leaf node but the deletion violates the minimum key property, borrow
a key from either its left sibling or right sibling.
Case 1c : If the key to be deleted is in a leaf node but neither of the sibling contain more than m/2 elements then
create a new leaf node by joining two leaf nodes and the intervening element of the parent node. (Delete 53)
35
Case 2 − If the key to be deleted is in an internal node, it is replaced by a key in either left child or right child based on which child has
more keys. But if both child nodes have minimum number of keys, they’re merged together.
Case 2: In this case, the height of the tree shrinks. If the target key lies in an internal node, and the deletion of the key leads to a
fewer number of keys in the node (i.e. less than the minimum required), then look for the inorder predecessor and the inorder
successor. If both the children contain a minimum number of keys then, borrowing cannot take place. This leads to merging the
children.
Again, look for the sibling to borrow a key. But, if the sibling also has only a minimum number of keys then, merge the node with
the sibling along with the parent. Arrange the children accordingly (increasing order).
Applications of B-Trees:
● It is used in large databases to access data stored on the disk
● Searching for data in a data set can be achieved in significantly less time using the B-Tree
● Most of the servers also use the B-tree approach.
● B-Trees are also used in other areas such as natural language processing, computer networks, and cryptography.
Advantages of B-Trees:
● B-Trees have a guaranteed time complexity of O(log n) for basic operations like insertion, deletion, and searching, which makes
them suitable for large data sets and real-time applications.
● Balanced tree structure: B-trees have a balanced tree structure that maintains a logarithmic depth.
● Scalable: B-trees can scale with large datasets.
● Flexibility in node size: B-trees offer flexibility in node size.
● Sequential access: B-trees allow for sequential access and range queries because keys are kept in sorted order
Disadvantages of B-Trees:
● Slow in comparison to other data structures.
● Complex implementation: B-trees can be complex to implement.
Performance degradation with small datasets: B-trees can have performance degradation with small datasets.
● Complex balancing operations: B-trees can have complex balancing operations.
● Require more space: B-tree indexes can require more space than other types of indexes.
● Not efficient for write-heavy workloads: B-tree indexes can be slower for write-heavy workloads
Huffman Coding

Huffman coding is a lossless data compression algorithm.

The idea is to assign variable-length codes to input characters, lengths of the assigned codes are based on the frequencies of
corresponding characters.

The variable-length codes assigned to input characters are Prefix Codes, means the codes (bit sequences) are assigned in such a way that
the code assigned to one character is not the prefix of code assigned to any other character.

It is used as a component in lossless compressions such as zip, gzip, and png, and even as part of lossy compression algorithms like mp3
and jpeg.
Why Huffman’s Encoding?
1. Fixed length encodings have the advantage of random
access. But it doesn't work efficiently when the elements have
an unequal probability of occurring.

2. Variable-length encodings :

A. When we try to decode " 0 1 1 0", it could mean :


● “ABBA” = 0 1 1 0
● “ADA” = 0 11 0
● “ABC” = 0 1 10

B. Huffman Code- based on Prefix Codes, no ambiguity present

● “ABBA” = 0 1 1 0
Huffman Coding
This algorithm builds a tree in bottom up manner.

● Count how often each piece of data occurs.


● Build a binary tree, starting with the nodes with the lowest count. The new parent node has the combined count of its child
nodes.
● The edge from a parent gets '0' for the left child, and '1' for the edge to the right child.
● In the finished binary tree, follow the edges from the root node, adding '0' or '1' for each branch, to find the new Huffman code
for each piece of data.
● Create the Huffman code by converting the data, piece-by-piece, into a binary code using the binary tree.
Step 1: Combine the minimum two nodes
character Frequency
a 5
b 9
c 12
d 13
e 16
f 45 12, 13, 16, 45

Step 2: Rearrange the nodes and combine min nodes

16, 45

16, 45
Step 3: Rearrange the nodes and combine min nodes

45

45
Step 4:

45

Step 5:
Steps to print codes from Huffman Tree:
Traverse the tree formed starting from the root. Maintain an auxiliary array. While moving to the left child, write 0 to the array. While moving
to the right child, write 1 to the array. Print the array when a leaf node is encountered.

character Frequency
a 5
b 9
c 12
d 13
e 16
f 45

character code-word
a 1100
b 1101
c 100
d 101
e 111
f 0
Q: string str = "abbcdbccdaabbeeebeab"

Character Frequency

a 4

b 7

c 3

d 2

e 4
Character Frequency/ Code
count

a 4 01

b 7 11

c 3 101

d 2 100

e 4 00
Decoding Huffman Code
1. Start from the left in the Huffman code, and look up each bit Character Frequency/ Code
sequence in the table. count
2. Match each code to the corresponding letter.
3. Continue until the entire Huffman code is decoded.
a 4 01

b 7 11

c 3 101
Example: 11011001100
d 2 100
babdbe
e 4 00

You might also like