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

ME DSA Data Structure Lab Record

Uploaded by

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

ME DSA Data Structure Lab Record

Uploaded by

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

VELAMMAL ENGINEERING COLLEGE, CHENNAI – 66

(An Autonomous Institution, Affiliated to Anna University, Chennai)

Course code 19CS6106L Semester I


Category PROFESSIONAL CORE COURSE (PCC) L T P C
Course Title DATA STRUCTURES AND ALGORITHMS
0 0 4 2
LABORATORY

COURSE OBJECTIVES

The aim of this laboratory is


 To familiarize various data structure implementations.
 To implement heap and various tree structures like AVL, Red-black, B-Tree and segment
trees.
 To understand efficient implementation of line segment intersection.
 To understand various search structures.
 To get understanding of problem to program mapping.

COURSE OUTCOMES

BLOOMS
CO. NO. COURSE OUTCOME
LEVEL
At the end of the course students will be able to
Achieve programming skill to convert a problem to a
CO1 C3
programming logic.
CO2 Apply suitable data structure for the problem in hand. C3
Implement heap and various tree structures like AVL, Red-
CO3 C3
black, B-Tree and segment trees.
CO4 Understand the usage of data structures for geometric problems. C4
CO5 Understand the importance of height balancing in search
C5
structures

LIST OF EXPERIMENTS

1. Binary Search Trees


2. Min/Max Heaps
3. Leftist Heaps
4. AVL Trees
5. Red-Black Trees
6. B-Trees
7. Segment Trees
8. Line segment intersection

1
Ex.No:1 IMPLEMENTATION OF BINARY SEARCH TREES
AIM

To write a C program to implement the binary search trees.

PRE LAB DISCUSSION

A binary search tree (BST) is a tree in which all nodes follows the below mentioned properties

The left sub-tree of a node has key less than or equal to its parent node'skey.
The right sub-tree of a node has key greater than or equal to its parent node's
key.Thus, a binary search tree (BST) divides all its sub-trees into two segments; left sub-
tree and right sub-tree and can be definedas
left_subtree (keys) ≤ node (key) ≤ right_subtree (keys)

Following are basic primary operations of a tree which are following.


Search − search an element in atree.
Insert − insert an element in atree.
Delete – removes an existing node from thetree
Preorder Traversal − traverse a tree in a preordermanner.
Inorder Traversal − traverse a tree in an inordermanner.
Postorder Traversal − traverse a tree in a postordermanner.

ALGORITHM

Step 1: Start the process.


Step 2: Initialize and declare variables.
Step 3: Construct the Tree
Step 4: Data values are given which we call a key and a binary search tree
Step 5: To search for the key in the given binary search tree, start with theroot
node and Compare the key with the data value of the root node. Ifthey

2
match, return the root pointer.
Step 6: If the key is less than the data value of the root node, repeat the process by
using the left subtree.
Step 7: Otherwise, repeat the same process with the right subtree until either a
match is found or the subtree under consideration becomes an empty tree.
Step 8:Terminate

PROGRAM
#include<stdio.h>
#include<conio.h>
#include<process.h>
#include<alloc.h>

struct tree
{
int data;
struct tree *lchild;
struct tree *rchild;
}*t,*temp;

int element;
void inorder(struct tree *);
void preorder(struct tree *);
void postorder(struct tree *);
struct tree * create(struct tree *, int);
struct tree * find(struct tree *, int);
struct tree * insert(struct tree *, int);
struct tree * del(struct tree *, int);
struct tree * findmin(struct tree *);
struct tree * findmax(struct tree *);
void main()
{
int ch;

do
{
printf("\n\t\t\tBINARY SEARCH TREE");
printf("\n\t\t\t****** ****** ****");
printf("\nMain Menu\n");
printf("\n1.Create\n2.Insert\n3.Delete\n4.Find\n5.FindMin\n6.FindMax");
printf("\n7.Inorder\n8.Preorder\n9.Postorder\n10.Exit\n");
printf("\nEnter ur choice :");
scanf("%d",&ch);
switch(ch)
{

3
case1:
printf("\nEnter the data:");
scanf("%d",&element);
t=create(t,element);
inorder(t);
break;
case2:
printf("\nEnter the data:");
scanf("%d",&element);
t=insert(t,element);
inorder(t);
case3: break;
printf("\nEnter the data:");
scanf("%d",&element);
t=del(t,element);
inorder(t);
case4: break;

printf("\nEnter the data:");


scanf("%d",&element);
temp=find(t,element);
if(temp->data==element)
printf("\nElement %d is at %d",element,temp);
else
printf("\nElement is not found");
break;
case 5:

temp=findmin(t);
printf("\nMax element=%d",temp->data);
break;
case6:
temp=findmax(t);
printf("\nMax element=%d",temp->data);
break;
case7:
inorder(t);
break;
case8:
preorder(t);
break;
case9:
postorder(t);
break;
case 10:exit(0);
4
}
}while(ch<=10);
}

struct tree * create(struct tree *t, int element)


{
t=(struct tree *)malloc(sizeof(structtree));
t->data=element;
t->lchild=NULL;
t->rchild=NULL;
return t;
}

struct tree * find(struct tree *t, int element)


{
if(t==NULL)
return NULL;
if(element<t->data)
return(find(t->lchild,element));
else
if(element>t->data)
return(find(t->rchild,element));
else
return t;
}

struct tree *findmin(struct tree *t)


{
if(t==NULL)
return NULL;
else
if(t->lchild==NULL)
return t;
else
return(findmin(t->lchild));
}

struct tree *findmax(struct tree *t)


{
if(t!=NULL)
{
while(t->rchild!=NULL)
t=t->rchild;
}
return t;
}
5
struct tree *insert(struct tree *t,int element)
{
if(t==NULL)
{
t=(struct tree *)malloc(sizeof(struct tree));
t->data=element;
t->lchild=NULL;
t->rchild=NULL;
return t;
}
else
{
if(element<t->data)
{
t->lchild=insert(t->lchild,element);
}
else
if(element>t->data)
{
t->rchild=insert(t->rchild,element);
}
else

if(element==t->data)
{
printf("element already present\n");
}
return t;
}
}

struct tree * del(struct tree *t, int element)


{
if(t==NULL)
printf("element not found\n");
else
if(element<t->data)
t->lchild=del(t->lchild,element);
else
if(element>t->data)
t->rchild=del(t->rchild,element);
else
if(t->lchild&&t->rchild)
{
temp=findmin(t->rchild);
t->data=temp->data;
6
t- >rchild=del(t->rchild,t->data);
}
else
{
temp=t;
if(t->lchild==NULL)
t=t->rchild;
else
if(t->rchild==NULL)
t=t->lchild;
free(temp);
}
return t;
}

void inorder(struct tree *t)


{
if(t==NULL)
return;
else
{
inorder(t->lchild);
printf("\t%d",t->data);
inorder(t->rchild);
}
}

void preorder(struct tree *t)


{
if(t==NULL)
return;
else
{
printf("\t%d",t->data);
preorder(t->lchild);
preorder(t->rchild);
}
}

void postorder(struct tree *t)


{
if(t==NULL)
return;
else
{
postorder(t->lchild);

7
postorder(t->rchild);
printf("\t%d",t->data);
}
}

OUTPUT

BINARY SEARCH TREE


****** ****** ****
Main Menu

1.
Cre
ate
2.I
nse
rt
3.D
elet
e
4.F
ind
5.F
ind
Mi
n
6.F
ind
Ma
x
7.I
nor
der
8.P
reo
rde
r
9.P
ost
ord
er
10.
Exi
t

Enter ur choice :1
8
Enter the data:10
10
BINARY SEARCH TREE
****** ****** ****
Main Menu
1.Create
2.Insert
3.Delete
4.Find
5.FindMin
6.FindMax
7.Inorder
8.Preorder
9.Postorder
10.Exit

Enter ur choice :2

Enter the data:20


10 20

9
BINARY SEARCH TREE

****** ****** ****


Main Menu

1.Create
2.Insert
3.Delete
4.Find
5.FindMin
6.FindMax
7.Inorder
8.Preorder
9.Postorder
10.Exit

Enter ur choice :2

Enter the data:30


10 20 30
BINARY SEARCH TREE
****** ****** ****
Main Menu

1.Create
2.Insert
3.Delete
4.Find
5.FindMin
6.FindMax
7.Inorder
8.Preorder
9.Postorder
10.Exit

Enter ur choice :2

Enter the data:25


10 20 25 30
BINARY SEARCH TREE
****** ****** ****

RESULT

Thus the C program to implement the binary search trees was completed successfully.
10
Ex.No:2 MIN AND MAX HEAPS

AIM

To write a C program to implement the concept of Min and Max Heaps.

ALGORITHM

Step 1: Start
Step 2: Create a new node at the end of heap.

Step 3: Assign new value to the node.

Step 4: Compare the value of this child node with its parent.

Step 5: If value of parent is less than child, then swap them.

Step 6: Repeat step 3 & 4 until Heap property holds


Step 7: Stop.

PROGRAM:

#include <stdio.h>
int size = 0;
void swap(int *a, int *b)
{
int temp = *b;
*b = *a;
*a = temp;
}
void heapify(int array[], int size, int i)
{
if (size == 1)
{
printf("Single element in the heap");
}
else
{
int largest = i;
11
int l = 2 * i + 1;
int r = 2 * i + 2;
if (l < size && array[l] > array[largest])
largest = l;
if (r < size && array[r] > array[largest])
largest = r;
if (largest != i)
{
swap(&array[i], &array[largest]);
heapify(array, size, largest);
}
}
}
void insert(int array[], int newNum)
{
if (size == 0)
{
array[0] = newNum;
size += 1;
}
else
{
array[size] = newNum;
size += 1;
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(array, size, i);
}
}
}
void deleteRoot(int array[], int num)
{
int i;
for (i = 0; i < size; i++)
{
if (num == array[i])
break;
}

12
swap(&array[i], &array[size - 1]);
size -= 1;
for (int i = size / 2 - 1; i >= 0; i--)
{
heapify(array, size, i);
}
}
void printArray(int array[], int size)
{
for (int i = 0; i < size; ++i)
printf("%d ", array[i]);
printf("\n");
}
int main()
{
int array[10];

insert(array, 3);
insert(array, 4);
insert(array, 9);
insert(array, 5);
insert(array, 2);

printf("Max-Heap array: ");


printArray(array, size);

deleteRoot(array, 4);

printf("After deleting an element: ");

printArray(array, size);
}

13
OUT PUT:

Max-Heap array: 9 5 4 3 2
After deleting an element: 9 5 2 3

RESULT:
Thus the ‘C’ program to implement Min and Max heaps was executed successfully.

14
Ex.No:3 LEFTIST HEAPS

AIM

To write a program to implement the concept of Leftist Heaps.

ALGORITHM

Step 1: Start the program

Step 2: Put the root with smaller value as the new root

Step 3: Hang its left sub tree on the left

Step 4: Recursively merge its right sub tree and the other tree

Step 5: Before returning from recursion:


– Update dist () of merged root.
– Swap left and right sub trees just below root, if needed, to keep leftist property of
merged

Step 6: Results and Stop the program.

PROGRAM:

#include <bits/stdc++.h>
using namespace std;

// Node Class Declaration


class LeftistNode
{
public:
int element;
LeftistNode *left;
LeftistNode *right;
int dist;
LeftistNode(int & element, LeftistNode *lt = NULL,
LeftistNode *rt = NULL, int np = 0)
{
this->element = element;
right = rt;
left = lt,
dist = np;
}
};
15
//Class Declaration
class LeftistHeap
{
public:
LeftistHeap();
LeftistHeap(LeftistHeap &rhs);
~LeftistHeap();
bool isEmpty();
bool isFull();
int &findMin();
void Insert(int &x);
void deleteMin();
void deleteMin(int &minItem);
void makeEmpty();
void Merge(LeftistHeap &rhs);
LeftistHeap & operator =(LeftistHeap &rhs);
private:
LeftistNode *root;
LeftistNode *Merge(LeftistNode *h1,
LeftistNode *h2);
LeftistNode *Merge1(LeftistNode *h1,
LeftistNode *h2);
void swapChildren(LeftistNode * t);
void reclaimMemory(LeftistNode * t);
LeftistNode *clone(LeftistNode *t);
};

// Construct the leftist heap


LeftistHeap::LeftistHeap()
{
root = NULL;
}

// Copy constructor.
LeftistHeap::LeftistHeap(LeftistHeap &rhs)
{
root = NULL;
*this = rhs;
}

// Destruct the leftist heap


LeftistHeap::~LeftistHeap()
{
makeEmpty( );
}

16
/* Merge rhs into the priority queue.
rhs becomes empty. rhs must be different
from this.*/
void LeftistHeap::Merge(LeftistHeap &rhs)
{
if (this == &rhs)
return;
root = Merge(root, rhs.root);
rhs.root = NULL;
}

/* Internal method to merge two roots.


Deals with deviant cases and calls recursive Merge1.*/
LeftistNode *LeftistHeap::Merge(LeftistNode * h1,
LeftistNode * h2)
{
if (h1 == NULL)
return h2;
if (h2 == NULL)
return h1;
if (h1->element < h2->element)
return Merge1(h1, h2);
else
return Merge1(h2, h1);
}

/* Internal method to merge two roots.


Assumes trees are not empty, and h1's root contains
smallest item.*/
LeftistNode *LeftistHeap::Merge1(LeftistNode * h1,
LeftistNode * h2)
{
if (h1->left == NULL)
h1->left = h2;
else
{
h1->right = Merge(h1->right, h2);
if (h1->left->dist < h1->right->dist)
swapChildren(h1);
h1->dist = h1->right->dist + 1;
}
return h1;
}

// Swaps t's two children.


void LeftistHeap::swapChildren(LeftistNode * t)
{

17
LeftistNode *tmp = t->left;
t->left = t->right;
t->right = tmp;
}

/* Insert item x into the priority queue, maintaining


heap order.*/
void LeftistHeap::Insert(int &x)
{
root = Merge(new LeftistNode(x), root);
}

/* Find the smallest item in the priority queue.


Return the smallest item, or throw Underflow if empty.*/
int &LeftistHeap::findMin()
{
return root->element;
}

/* Remove the smallest item from the priority queue.


Throws Underflow if empty.*/
void LeftistHeap::deleteMin()
{
LeftistNode *oldRoot = root;
root = Merge(root->left, root->right);
delete oldRoot;
}

/* Remove the smallest item from the priority queue.


Pass back the smallest item, or throw Underflow if empty.*/
void LeftistHeap::deleteMin(int &minItem)
{
if (isEmpty())
{
cout<<"Heap is Empty"<<endl;
return;
}
minItem = findMin();
deleteMin();
}

/* Test if the priority queue is logically empty.


Returns true if empty, false otherwise*/
bool LeftistHeap::isEmpty()
{
return root == NULL;
}

18
/* Test if the priority queue is logically full.
Returns false in this implementation.*/
bool LeftistHeap::isFull()
{
return false;
}

// Make the priority queue logically empty


void LeftistHeap::makeEmpty()
{
reclaimMemory(root);
root = NULL;
}

// Deep copy
LeftistHeap &LeftistHeap::operator =(LeftistHeap & rhs)
{
if (this != &rhs)
{
makeEmpty();
root = clone(rhs.root);
}
return *this;
}

// Internal method to make the tree empty.


void LeftistHeap::reclaimMemory(LeftistNode * t)
{
if (t != NULL)
{
reclaimMemory(t->left);
reclaimMemory(t->right);
delete t;
}
}

// Internal method to clone subtree.


LeftistNode *LeftistHeap::clone(LeftistNode * t)
{
if (t == NULL)
return NULL;
else
return new LeftistNode(t->element, clone(t->left),
clone(t->right), t->dist);
}

19
//Driver program
int main()
{
LeftistHeap h;
LeftistHeap h1;
LeftistHeap h2;
int x;
int arr[]= {1, 5, 7, 10, 15};
int arr1[]= {22, 75};

h.Insert(arr[0]);
h.Insert(arr[1]);
h.Insert(arr[2]);
h.Insert(arr[3]);
h.Insert(arr[4]);
h1.Insert(arr1[0]);
h1.Insert(arr1[1]);

h.deleteMin(x);
cout<< x <<endl;

h1.deleteMin(x);
cout<< x <<endl;

h.Merge(h1);
h2 = h;

h2.deleteMin(x);
cout<< x << endl;

return 0;
}

OUTPUT:

1
22
5

RESULT:
Thus the program to implement Leftist Heaps was executed successfully.

20
Ex.No:4 IMPLEMENTATION OF AVL TREES

AIM

To write a C program to implement AVL trees.

PRE LAB DISCUSSION

AVL tree is a self-balanced binary search tree. That means, an AVL tree is also a binary
search tree but it is a balanced tree. A binary tree is said to be balanced, if the difference between
the heights of left and right sub trees of every node in the tree is either -1, 0 or +1. In other
words, a binary tree is said to be balanced if for every node, height of its children differ by at
most one. In an AVL tree, every node maintains a extra information known as balance factor.
An AVL tree is defined as follows...

An AVL tree is a balanced binary search tree. In an AVL tree, balance factor of every node is
-1, 0 or +1.

Balance factor of a node is the difference between the heights of left and right subtrees of that
node. The balance factor of a node is calculated either height of left subtree - height of right
subtree (OR) height of right subtree - height of left subtree.

AVL Tree Rotations

In AVL tree, after performing every operation like insertion and deletion we need to check the
balance factor of every node in the tree. If every node satisfies the balance factor condition then
we conclude the operation otherwise we must make it balanced. We use rotation operations to
make the tree balanced whenever the tree is becoming imbalanced due to any operation.

Rotation operations are used to make a tree balanced.

Rotation is the process of moving the nodes to either left or right to make tree balanced.

21
There are four rotations and they are classified into two types.

ALGORITHM

Step 1: Start
Step 2: Insert the new element into the tree using Binary Search Tree insertion logic.
Step 3: After insertion, check the Balance Factor of every node.
 If the Balance Factor of every node is 0 or 1 or -1 then go for nextoperation.
 If the Balance Factor of any node is other than 0 or 1 or -1 then tree is said to be
imbalanced. Then perform the suitable Rotation to make it balanced. And go for
next operation.
Step 4: Compare, the search element with the value of root node in the tree.
If search element is larger, then continue the search process in right subtree.
If we reach to the node with search value, then display "Element is found" and
terminate the function.
Step 5: Stop

22
PROGRAM

#include<stdio.h>
#include<malloc.h>
typedef enum { FALSE ,TRUE } ;
struct node
{
int info;
int balance;
struct node *lchild;
struct node *rchild;
};
struct node *insert (int , struct node *, int *);
struct node* search(struct node *,int);

struct node* search(struct node *ptr,int info)


{
if(ptr!=NULL)
if(info < ptr->info)
ptr=search(ptr->lchild,info);
else if( info > ptr->info)
ptr=search(ptr->rchild,info);
return(ptr);
}/*End of search()*/

struct node *insert (int info, struct node *pptr, int *ht_inc)
{
struct node *aptr;
struct node *bptr;
if(pptr==NULL)
{
pptr = (struct node *) malloc(sizeof(structnode));
pptr->info =info;
pptr->lchild = NULL;
pptr->rchild = NULL;
pptr->balance = 0;
*ht_inc = TRUE;
return (pptr);
}
if(info < pptr->info)
{
pptr->lchild = insert(info, pptr->lchild, ht_inc);
if(*ht_inc==TRUE)
{
switch(pptr->balance)
{
case -1: /* Right heavy */

23
pptr->balance = 0;
*ht_inc = FALSE;
break;
case 0: /* Balanced */
pptr->balance = 1;
break;
case 1: /* Left heavy */
aptr = pptr->lchild;
if(aptr->balance == 1)
{
printf("Left to Left Rotation\n");
pptr->lchild= aptr->rchild;
aptr->rchild = pptr;
pptr->balance = 0;
aptr->balance=0;
pptr = aptr;
}
else
{
printf("Left to rightrotation\n");
bptr =aptr->rchild;
aptr->rchild =bptr->lchild;
bptr->lchild =aptr;
pptr->lchild =bptr->rchild;
bptr->rchild =pptr;

if(bptr->balance == 1 )
pptr->balance = -1;
else
pptr->balance = 0;
if(bptr->balance == -1)
aptr->balance = 1;
else
aptr->balance = 0;
bptr->balance=0;
pptr=bptr;
}
*ht_inc = FALSE;
}/*End of switch */
}/*End of if */
}/*End of if*/
if(info > pptr->info)
{
pptr->rchild = insert(info, pptr->rchild, ht_inc);
if(*ht_inc==TRUE)
{

24
switch(pptr->balance)
{
case 1: /* Left heavy */
pptr->balance = 0;
*ht_inc = FALSE;
break;
case 0: /* Balanced */
pptr->balance = -1;
break;
case -1: /* Right heavy */
aptr = pptr->rchild;
if(aptr->balance == -1)
{
printf("Right to Right Rotation\n");
pptr->rchild= aptr->lchild;
aptr->lchild = pptr;
pptr->balance = 0;
aptr->balance=0;
pptr = aptr;
}
else
{
printf("Right to LeftRotation\n");
bptr =aptr->lchild;
aptr->lchild =bptr->rchild;
bptr->rchild =aptr;
pptr->rchild =bptr->lchild;
bptr->lchild =pptr;
if(bptr->balance == -1)
pptr->balance = 1;
else
pptr->balance = 0;
if(bptr->balance == 1)
aptr->balance = -1;
else
aptr->balance = 0;
bptr->balance=0;
pptr = bptr;
}/*End of else*/
*ht_inc = FALSE;
}/*End of switch */
}/*End of if*/
}/*End of if*/

return(pptr);
}/*End of insert()*/

25
void display(struct node *ptr,int level)
{
int i;
if ( ptr!=NULL )
{
display(ptr->rchild, level+1);
printf("\n");
for (i = 0; i < level; i++)
printf(" ");
printf("%d", ptr->info);
display(ptr->lchild, level+1);
}/*End of if*/
}/*End of display()*/

void inorder(struct node *ptr)


{
if(ptr!=NULL)
{
inorder(ptr->lchild);
printf("%d ",ptr->info);
inorder(ptr->rchild);
}
}/*End of inorder()*/
main()
{
int ht_inc;
int info ;
int choice;
struct node *root = (struct node *)malloc(sizeof(struct node));
root = NULL;

while(1)
{
printf("1.Insert\n");
printf("2.Display\n");
printf("3.Quit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("Enter the value to be inserted : ");
scanf("%d", &info);
if( search(root,info) == NULL )
root = insert(info, root, &ht_inc);

26
else
printf("Duplicate value ignored\n");
break;
case 2:

if(root==NULL)
{
printf("Tree is empty\n");
continue;
}
printf("Tree is :\n");
display(root, 1);
printf("\n\n");
printf("Inorder Traversal is: ");
inorder(root);
printf("\n");
case 3: break;

default: exit(1);

printf("Wrong choice\n");

}/*End of switch*/
}/*End of while*/
}/*End of main()*/

OUTPUT:

27
RESULT

Thus the C program to implement AVL tree was completed successful

28
Ex.No:5 RED-BLACK TREES

AIM

To write a C program to implement the concept of Red-Black Trees.

ALGORITHM:
Step 1: Start the program.
Step 2: Perform standard BST insertion and make the color of newly inserted nodes as RED.
Step 3: If x is root, change color of x as BLACK (Black height of complete tree increases by 1).
Step 4: Do following if color of x’s parent is not BLACK or x is not root.
If x’s uncle is RED (Grand parent must have been black from property 4)
1. Change color of parent and uncle as BLACK.
2. color of grand parent as RED.
3. Change x = x’s grandparent, repeat steps 2 and 3 for new x.
Step 5: Stop the program.

PROGRAM:

#include <stdio.h>
#include <stdlib.h>

// Structure to represent each


// node in a red-black tree
struct node {
int d; // data
int c; // 1-red, 0-black
struct node* p; // parent
struct node* r; // right-child
struct node* l; // left child
};

// global root for the entire tree


struct node* root = NULL;

// function to perform BST insertion of a node


struct node* bst(struct node* trav,
struct node* temp)
{ 29
// If the tree is empty,
// return a new node
if (trav == NULL)
return temp;

// Otherwise recur down the tree


if (temp->d < trav->d)
{
trav->l = bst(trav->l, temp);
trav->l->p = trav;
}
else if (temp->d > trav->d)
{
trav->r = bst(trav->r, temp);
trav->r->p = trav;
}

// Return the (unchanged) node pointer


return trav;
}

// Function performing right rotation


// of the passed node
void rightrotate(struct node* temp)
{
struct node* left = temp->l;
temp->l = left->r;
if (temp->l)
temp->l->p = temp;
left->p = temp->p;
if (!temp->p)
root = left;
else if (temp == temp->p->l)
temp->p->l = left;
else
temp->p->r = left;
left->r = temp;
temp->p = left;
}

// Function performing left rotation


// of the passed node
30
void leftrotate(struct node* temp)
{
struct node* right = temp->r;
temp->r = right->l;
if (temp->r)
temp->r->p = temp;
right->p = temp->p;
if (!temp->p)
root = right;
else if (temp == temp->p->l)
temp->p->l = right;
else
temp->p->r = right;
right->l = temp;
temp->p = right;
}

// This function fixes violations


// caused by BST insertion
void fixup(struct node* root, struct node* pt)
{
struct node* parent_pt = NULL;
struct node* grand_parent_pt = NULL;

while ((pt != root) && (pt->c != 0)


&& (pt->p->c == 1))
{
parent_pt = pt->p;
grand_parent_pt = pt->p->p;

/* Case : A
Parent of pt is left child
of Grand-parent of
pt */
if (parent_pt == grand_parent_pt->l)
{

struct node* uncle_pt = grand_parent_pt->r;

/* Case : 1
The uncle of pt is also red
Only Recoloring required */
if (uncle_pt != NULL && uncle_pt->c == 1)
31
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
uncle_pt->c = 0;
pt = grand_parent_pt;
}

else {

/* Case : 2
pt is right child of its parent
Left-rotation required */
if (pt == parent_pt->r) {
leftrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}

/* Case : 3
pt is left child of its parent
Right-rotation required */
rightrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}

/* Case : B
Parent of pt is right
child of Grand-parent of
pt */
else {
struct node* uncle_pt = grand_parent_pt->l;

/* Case : 1
The uncle of pt is also red
Only Recoloring required */
if ((uncle_pt != NULL) && (uncle_pt->c == 1))
{
grand_parent_pt->c = 1;
parent_pt->c = 0;
32
uncle_pt->c = 0;
pt = grand_parent_pt;
}
else {
/* Case : 2
pt is left child of its parent
Right-rotation required */
if (pt == parent_pt->l) {
rightrotate(parent_pt);
pt = parent_pt;
parent_pt = pt->p;
}

/* Case : 3
pt is right child of its parent
Left-rotation required */
leftrotate(grand_parent_pt);
int t = parent_pt->c;
parent_pt->c = grand_parent_pt->c;
grand_parent_pt->c = t;
pt = parent_pt;
}
}
}

root->c = 0;
}

// Function to print inorder traversal


// of the fixated tree
void inorder(struct node* trav)
{
if (trav == NULL)
return;
inorder(trav->l);
printf("%d ", trav->d);
inorder(trav->r);
}

// driver code
int main()
{
int n = 7;
33
int a[7] = { 7, 6, 5, 4, 3, 2, 1 };

for (int i = 0; i < n; i++) {


// allocating memory to the node and initializing:
// 1. color as red
// 2. parent, left and right pointers as NULL
// 3. data as i-th value in the array
struct node* temp
= (struct node*)malloc(sizeof(struct node));
temp->r = NULL;
temp->l = NULL;
temp->p = NULL;
temp->d = a[i];
temp->c = 1;

// calling function that performs bst insertion of


// this newly created node
root = bst(root, temp);

// calling function to preserve properties of rb


// tree
fixup(root, temp);
}

printf("Inorder Traversal of Created Tree\n");


inorder(root);

return 0;
}

OUTPUT:
Inorder Traversal of Created Tree
1 2 3 4 5 6 7

Level Order Traversal of Created Tree


6 4 7 2 5 1 3

RESULT:
Thus the C program to implement Red-Black Trees was executed successfully.

34
Ex.No:6 IMPLEMENTATION OF BINARY TREES AND OPERATIONS OF BINARY TREES

AIM

To write a C program to implement the binary trees and its operations.

PRE LAB DISCUSSION

A binary tree is a tree data structure in which each node has at most two children,
which are referred to as the left child and the right child.

Insertion:
In binary trees, a new node before insert has to specify 1) whose child it is going to be 2)
mention whether new node goes as left/right child. For example(below image),

To add a new node to leaf node, a new node should also mention whether new node
goes as left/right child.

Deletion:
35
For deletion, only certain nodes in a binary tree can be removed unambiguously.
Suppose that the node to delete is node A. If A has no children, deletion is accomplished by
setting the child of A's parent to null. If A has one child, set the parent of A's child to A's
parent and set the child of A's parent to A's child. In a binary tree, a node with two children
cannot be deleted unambiguously.

ALGORITHM

Step 1: Start.
Step 2: Create a Binary Tree for N
elements. Step 3: Insert an element in
binary tree
Step 4: Traverse the tree in
inorder. Step 5: Traverse the tree
in preorder Step 6: Traverse the
tree in postorder. Step 7: Stop

PROGRAM

#include<stdio
.h>
#include<coni
o.h> struct
node
{
int data;
struct node
*rlink; struct
node *llink;
}*tmp=NULL;
typedef struct node
NODE; NODE
*create();
void preorder(NODE
*); void
inorder(NODE *);
void postorder(NODE
*);
void insert(NODE *);
void main()
{
int n,i,m;
clrs
cr(); 36
do
{
printf(“\n\n0.create\n\n1.insert \n\n2.preorder\n\n3.postorder\n\n4.inorder\n\n5.exit\n\
n”); printf(“\n\nEnter ur choice”);
scanf(“%d”,&m)
; switch(m)
{
case 0:
tmp=create(
); break;
case 1:
insert(t
mp);
break;
case 2:
printf(“\n\nDisplay tree in Preorder traversal\n\
n”); preorder(tmp);
bre
ak;
cas
e
3:
printf(“\n\nDisplay Tree in Postorder\n\
n”); postorder(tmp);
bre
ak;
cas
ee
4:
printf(“\n\nInorder\n\
n”); inorder(tmp);
br
ea
k;
ca
se
5:
exit(0);
}
}
while(n!=5);

getch();
}
void insert(NODE *root)
{
NODE
*newnode;
if(root==NUL
L)
{
newnode=creat
37
e();
root=newnode;
else
{
newnode=creat
e(); while(1)
{
if(newnode->data<root->data)
{
if(root->llink==NULL)
{
root-
>llink=newnode;
break;
}
root=root->llink;
}
if(newnode->data>root->data)
{
if(root->rlink==NULL)
{
root-
>rlink=newnode;
break;
}
root=root->rlink;
}
}
}
}
NODE *create()
{
NODE
*newnode; int
n;
newnode=(NODE*)malloc(sizeof(NOD
E)); printf(“\n\nEnter the Data “);
scanf(“%d”,&n);
newnode->data=n;
newnode-
>llink=NULL;
newnode-
>rlink=NULL;
return(newnode);
}

void postorder(NODE *tmp)

{
if(tmp!=NULL)
{
postorder(tmp->llink); 38
postorder(tmp->rlink);
printf(“%d->”,tmp-
>data);
}
}
void inorder(NODE *tmp)
{
if(tmp!=NULL)
{
inorder(tmp->llink);
printf(“%d->”,tmp-
>data); inorder(tmp-
>rlink);
}
}
void preorder(NODE *tmp)
{
if(tmp!=NULL)
{
printf(“%d->”,tmp-
>data); preorder(tmp-
>llink); preorder(tmp-
>rlink);
}
}

OUTPUT

0. Creat

1.insert

2.preor

der

3.posto

rder

4.inord

er

5.exit

Enter ur choice 0 39

Enter the Data 3


Enter ur choice 1

Enter the Data 7

Enter ur choice3

Display tree in Postorder 4 -> 6 -> 8 -> 7

->3 Enter ur choice4

Inorder

3 -> 4 -> 6 -> 7 -> 8

Enter ur choice 5

RESULT

Thus the C program to implement binary tree and its operation was
completed successfully.
40
Ex.No:7 SEGMENT TREES IMPLEMENTAION

AIM

To write a C program to implement the concept of Segment Trees.

PROGRAM
#include <stdio.h>
#include <math.h>

// A utility function to get the middle index from corner indexes.


int getMid(int s, int e) { return s + (e -s)/2; }

/* A recursive function to get the sum of values in given range


of the array. The following are parameters for this function.

st --> Pointer to segment tree


si --> Index of current node in the segment tree. Initially
0 is passed as root is always at index 0
ss & se --> Starting and ending indexes of the segment represented
by current node, i.e., st[si]
qs & qe --> Starting and ending indexes of query range */
int getSumUtil(int *st, int ss, int se, int qs, int qe, int si)
{
// If segment of this node is a part of given range, then return
// the sum of the segment
if (qs <= ss && qe >= se)
return st[si];

// If segment of this node is outside the given range


if (se < qs || ss > qe)
return 0;

// If a part of this segment overlaps with the given range


int mid = getMid(ss, se);
return getSumUtil(st, ss, mid, qs, qe, 2*si+1) +
getSumUtil(st, mid+1, se, qs, qe, 2*si+2);
}

41
/* A recursive function to update the nodes which have the given
index in their range. The following are parameters
st, si, ss and se are same as getSumUtil()
i --> index of the element to be updated. This index is
in the input array.
diff --> Value to be added to all nodes which have i in range */
void updateValueUtil(int *st, int ss, int se, int i, int diff, int si)
{
// Base Case: If the input index lies outside the range of
// this segment
if (i < ss || i > se)
return;

// If the input index is in range of this node, then update


// the value of the node and its children
st[si] = st[si] + diff;
if (se != ss)
{
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i, diff, 2*si + 1);
updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);
}
}

// The function to update a value in input array and segment tree.


// It uses updateValueUtil() to update the value in segment tree
void updateValue(int arr[], int *st, int n, int i, int new_val)
{
// Check for erroneous input index
if (i < 0 || i > n-1)
{
printf("Invalid Input");
return;
}

// Get the difference between new value and old value


int diff = new_val - arr[i];

42
// Update the value in array
arr[i] = new_val;

// Update the values of nodes in segment tree


updateValueUtil(st, 0, n-1, i, diff, 0);
}

// Return sum of elements in range from index qs (query start)


// to qe (query end). It mainly uses getSumUtil()
int getSum(int *st, int n, int qs, int qe)
{
// Check for erroneous input values
if (qs < 0 || qe > n-1 || qs > qe)
{
printf("Invalid Input");
return -1;
}

return getSumUtil(st, 0, n-1, qs, qe, 0);


}

// A recursive function that constructs Segment Tree for array[ss..se].


// si is index of current node in segment tree st
int constructSTUtil(int arr[], int ss, int se, int *st, int si)
{
// If there is one element in array, store it in current node of
// segment tree and return
if (ss == se)
{
st[si] = arr[ss];
return arr[ss];
}

// If there are more than one elements, then recur for left and
// right subtrees and store the sum of values in this node
int mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss, mid, st, si*2+1) +
constructSTUtil(arr, mid+1, se, st, si*2+2);
return st[si];

43
}

/* Function to construct segment tree from given array. This function


allocates memory for segment tree and calls constructSTUtil() to
fill the allocated memory */
int *constructST(int arr[], int n)
{
// Allocate memory for the segment tree

//Height of segment tree


int x = (int)(ceil(log2(n)));

//Maximum size of segment tree


int max_size = 2*(int)pow(2, x) - 1;

// Allocate memory
int *st = new int[max_size];

// Fill the allocated memory st


constructSTUtil(arr, 0, n-1, st, 0);

// Return the constructed segment tree


return st;
}

// Driver program to test above functions


int main()
{
int arr[] = {1, 3, 5, 7, 9, 11};
int n = sizeof(arr)/sizeof(arr[0]);

// Build segment tree from given array


int *st = constructST(arr, n);

// Print sum of values in array from index 1 to 3


printf("Sum of values in given range = %dn",
getSum(st, n, 1, 3));

// Update: set arr[1] = 10 and update corresponding


// segment tree nodes
44
updateValue(arr, st, n, 1, 10);

// Find sum after the value is updated


printf("Updated sum of values in given range = %dn",
getSum(st, n, 1, 3));
return 0;
}

OUTPUT:
Sum of values in given range = 15
Updated sum of values in given range = 22

RESULT

Thus the C program to implement linear search was executed successfully

45
Ex.No:8 LINE SEGMENT INTERSECTION

AIM

To write a C program to implement the concept of Line segment intersection.

PROGRAM:
#include <bits/stdc++.h>
using namespace std;

// A point in 2D plane
struct Point
{
int x, y;
};

// A line segment with left as Point


// with smaller x value and right with
// larger x value.
struct Segment
{
Point left, right;
};
// An event for sweep line algorithm
// An event has a point, the position
// of point (whether left or right) and
// index of point in the original input
// array of segments.
struct Event {
int x, y;
bool isLeft;
int index;
Event(int x, int y, bool l, int i) : x(x), y(y), isLeft(l), index(i) {}

// This is for maintaining the order in set.


bool operator<(const Event& e) const {
if(y==e.y)return x<e.x;
46
return y < e.y;
}
};

// Given three collinear points p, q, r, the function checks if


// point q lies on line segment 'pr'
bool onSegment(Point p, Point q, Point r)
{
if (q.x <= max(p.x, r.x) && q.x >= min(p.x, r.x) &&
q.y <= max(p.y, r.y) && q.y >= min(p.y, r.y))
return true;

return false;
}

// To find orientation of ordered triplet (p, q, r).


// The function returns following values
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
// for details of below formula.
int val = (q.y - p.y) * (r.x - q.x) -
(q.x - p.x) * (r.y - q.y);

if (val == 0) return 0; // collinear

return (val > 0)? 1: 2; // clock or counterclock wise


}

// The main function that returns true if line segment 'p1q1'


// and 'p2q2' intersect.
bool doIntersect(Segment s1, Segment s2)
{
Point p1 = s1.left, q1 = s1.right, p2 = s2.left, q2 = s2.right;

47
// Find the four orientations needed for general and
// special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);

// General case
if (o1 != o2 && o3 != o4)
return true;

// Special Cases
// p1, q1 and p2 are collinear and p2 lies on segment p1q1
if (o1 == 0 && onSegment(p1, p2, q1)) return true;

// p1, q1 and q2 are collinear and q2 lies on segment p1q1


if (o2 == 0 && onSegment(p1, q2, q1)) return true;

// p2, q2 and p1 are collinear and p1 lies on segment p2q2


if (o3 == 0 && onSegment(p2, p1, q2)) return true;

// p2, q2 and q1 are collinear and q1 lies on segment p2q2


if (o4 == 0 && onSegment(p2, q1, q2)) return true;

return false; // Doesn't fall in any of the above cases


}

// Find predecessor of iterator in s.


set<Event>::iterator pred(set<Event> &s, set<Event>::iterator it) {
return it == s.begin() ? s.end() : --it;
}

// Find successor of iterator in s.


set<Event>::iterator succ(set<Event> &s, set<Event>::iterator it) {
return ++it;
}

// Returns true if any two lines intersect.


48
int isIntersect(Segment arr[], int n)
{
unordered_map<string,int> mp; // to note the pair for which intersection is checked already
// Pushing all points to a vector of events
vector<Event> e;
for (int i = 0; i < n; ++i) {
e.push_back(Event(arr[i].left.x, arr[i].left.y, true, i));
e.push_back(Event(arr[i].right.x, arr[i].right.y, false, i));
}

// Sorting all events according to x coordinate.


sort(e.begin(), e.end(), [](Event &e1, Event &e2) {return e1.x < e2.x;});

// For storing active segments.


set<Event> s;
int ans=0;
// Traversing through sorted points
for (int i=0; i<2*n; i++)
{
Event curr = e[i];
int index = curr.index;

// If current point is left of its segment


if (curr.isLeft)
{
// Get above and below points
auto next = s.lower_bound(curr);
auto prev = pred(s, next);
// Check if current point intersects with
// any of its adjacent
bool flag=false;
if (next != s.end() && doIntersect(arr[next->index], arr[index])){
string s=to_string(next->index+1)+" "+to_string(index+1);
if(mp.count(s)==0){mp[s]++;ans++;} //if not already checked we can increase count in map
}
if (prev != s.end() && doIntersect(arr[prev->index], arr[index])){
string s=to_string(prev->index+1)+" "+to_string(index+1);
if(mp.count(s)==0){mp[s]++;ans++;} //if not already checked we can increase count in map
}
49
// if same line segment is there then decrease answer as it got increased twice
if(prev != s.end() && next != s.end() && next->index==prev->index)ans--;

// Insert current point (or event)


s.insert(curr);
}

// If current point is right of its segment


else
{
// Find the iterator
auto it=s.find(Event(arr[index].left.x, arr[index].left.y, true, index));
// Find above and below points
auto next = succ(s, it);
auto prev = pred(s, it);

// If above and below point intersect


if (next != s.end() && prev != s.end())
{ string s=to_string(next->index+1)+" "+to_string(prev->index+1);
string s1=to_string(prev->index+1)+" "+to_string(next->index+1);
if (mp.count(s)==0&&mp.count(s1)==0&&doIntersect(arr[prev->index], arr[next->index]))
ans++;
mp[s]++;
}

// Remove current segment


s.erase(it);
}
}
//print pair of lines having intersection

for(auto &pr:mp){
cout<<pr.first<<"\n";
}
return ans;
}
// Driver code
int main() {
50
Segment arr[] = { {{1, 5}, {4, 5}}, {{2, 5}, {10, 1}},{{3, 2}, {10, 3}},{{6, 4}, {9, 4}},{{7, 1}, {8,
1}}};
int n = sizeof(arr)/sizeof(arr[0]);
cout<<isIntersect(arr, n);
return 0;

OUTPUT:
0

RESULT:
Thus the C program to implement the binary search was completed successfully.

51

You might also like