Download as pdf or txt
Download as pdf or txt
You are on page 1of 52

INDEX

EXPERIMENT OBJECTIVE DONE SIGNATURE


NO: ON:

13 Write a C/C++ program to check 10/10/2022


whether the given string is
Palindrome or not using Double
Ended Queue (DEQUE).
14 Write a C/C++ program to 10/10/2022
implement Tower of Hanoi
Problem using Stack.

15 Write a C/C++ program to 10/10/2022


implement the Linked List Data
structure and insert a new node at
the beginning, and at a given
position.

16 Write a C/C++ program to split a 10/10/2022


given linked list into two sub-list
as Front sub-list and Back sub-
list, if odd number of the element
then add the last element into the
front list.

17 Given a Sorted doubly linked list 10/10/2022


of positive integers and an
integer, finds all the pairs (sum of
two nodes data part) that is equal
to the given integer value.
Example: Double Linked List 2, 5,
7, 8, 9, 10, 12, 16, 19, 25, and P=35
then pairs will be Pairs will be (10,
25), (16, 19).

18 Write a C/C++ program to 17/10/2022


implement Stack Data Structure
using Queue.

19 Write a C/C++ program to 17/10/2022


implement Queue Data Structure
using Stack.

20 Write a C/C++ program to 24/10/2022


implement the Binary Tree using
linked list and perform In-order
traversal.

21 Write a C/C++ program to check 24/10/2022


whether the given tree is a Binary
Search Tree or not.

22 Write a C/C++ program to 31/10/2022


implement insertion in the AVL
tree.

23 Write a C/C++ program to Delete 31/10/2022


a key from the AVL tree.

24 Write a C/C++ program to count 31/10/2022


the number of leaf nodes in an
AVL tree.
EXPERIMENT -13

AIM:
Write a C/C++ program to check whether the given string is Palindrome or not using
Double Ended Queue (DEQUE).

THEORY:
In Dequeue we can push and pop elements from both front and rear. Hence we can
push the characters of string in dequeue, check if front and rear elements are equal. If
front and rear elements are not equal at any point then return false. Else return true.

ALGORITHM:
The solution to this problem will use a deque to store the characters of the string.
• We will process the string from left to right and add each character to the rear of
the deque. At this point, the deque will be acting very much like an ordinary
queue. However, we can now make use of the dual functionality of the deque.
The front of the deque will hold the first character of the string and the rear of the
deque will hold the last character.
• Since we can remove both of them directly, we can compare them and continue
only if they match.
• If we can keep matching first and the last items, we will eventually either run out
of characters or be left with a deque of size 1 depending on whether the length of
the original string was even or odd. In either case, the string must be a
palindrome.
• If in any case first and the last item didn’t match then the string is not a
palindrome.

CODE:
#include <iostream>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
void display(deque<char> q)
{
while (!q.empty())
{ cout << q.front() << " ";
q.pop_front(); }
}
bool checkPalindrome(deque<char> q)
{
if (q.size() == 0)
return 1;
else if (q.size() == 1){
return 1;
}
else{
while (!q.empty()){
if (q.front() != q.back()){
return 0;
}
else{
if (q.size() <= 1){
return 1;
}
q.pop_back();
q.pop_front();
}}}
return 1;
}
int main(){
string s;
cout << "Enter the string:";
cin >> s;
deque<char> q;
for (int i = 0; i < s.length(); i++){
q.push_back(s[i]);
}
if (checkPalindrome(q)){
cout << "String is palindrome" << endl;
}
else{
cout << "String is not palindrome" << endl;
}
return 0;
}

OUTPUT:

CASE-1: String is palindrome


CASE-2: String is not palindrome
EXPERIMENT -14

AIM:
Write a C/C++ program to implement Tower of Hanoi Problem using Stack.

THEORY:
Tower of Hanoi is a mathematical puzzle where we have three rods (A, B, and C) and N
disks. Initially, all the disks are stacked in decreasing value of diameter i.e., the smallest
disk is placed on the top and they are on rod A. The objective of the puzzle is to move
the entire stack to another rod (here considered C), obeying the following simple rules:
• Only one disk can be moved at a time.
• Each move consists of taking the upper disk from one of the stacks and placing it
on top of another stack i.e. a disk can only be moved if it is the uppermost disk
on a stack.
• No disk may be placed on top of a smaller disk.

ALGORITHM:
• Create a function towerOfHanoi where pass the N (current number of disk),
from_rod, to_rod, aux_rod.
• Make a function call for N – 1 th disk.
• Then print the current the disk along with from_rod and to_rod
• Again make a function call for N – 1 th disk.

CODE:
#include <bits/stdc++.h>
using namespace std;
int transfer_disk(stack<int>& a,stack<int>& b){
if(b.empty()==true){
b.push(a.top());
a.pop();
return 1;
}
else if(a.empty()==true){
a.push(b.top());
b.pop();
return 2;
}
else{
if(b.top()>a.top()){
b.push(a.top());
a.pop();
return 1;
}
else{
a.push(b.top());
b.pop();
return 2;
}}
}
int main(){
stack<int> s,a,d;
int n=0;
cin>>n;
for(int i=n;i>=1;i--){
s.push(i);
}
int x=pow(2,n)-1;
int i=1;
if(n%2==0){
while(i<=x){
if(i%3==1){
int y=transfer_disk(s,a);
if(y==1){
cout<<"Move the disk "<<a.top()<<" from source to auxiliary"<<endl;
}
else
cout<<"Move the disk "<<s.top()<<" from auxiliary to source"<<endl;
}
else if(i%3==2){
int y=transfer_disk(s,d);
if(y==1){
cout<<"Move the disk "<<d.top()<<" from source to destination"<<endl;
}
else
cout<<"Move the disk "<<s.top()<<" from destination to source"<<endl;
}
else{
int y=transfer_disk(a,d);
if(y==1){
cout<<"Move the disk "<<d.top()<<" from auxiliary to destination"<<endl;
}
else
cout<<"Move the disk "<<a.top()<<" from destination to auxiliary"<<endl;
}
i++;
}
}
else{
while(i<=x){
if(i%3==1){
int y=transfer_disk(s,d);
if(y==1){
cout<<"Move the disk "<<d.top()<<" from source to destination"<<endl;
}
else
cout<<"Move the disk "<<s.top()<<" from destination to source"<<endl;
}
else if(i%3==2){
int y=transfer_disk(s,a);
if(y==1){
cout<<"Move the disk "<<a.top()<<" from source to auxiliary"<<endl;
}
else
cout<<"Move the disk "<<s.top()<<" from auxiliary to source"<<endl;
}
else{
int y=transfer_disk(a,d);
if(y==1){
cout<<"Move the disk "<<d.top()<<" from auxiliary to destination"<<endl;
}
else
cout<<"Move the disk "<<a.top()<<" from destination to auxiliary"<<endl;
}
i++;
}}
while(d.empty()!=true){
cout<<d.top()<<endl;
d.pop();
}
return 0; }

OUTPUT:
EXPERIMENT -15

AIM:
Write a C/C++ program to implement the Linked List Data structure and insert a new
node at the beginning, and at a given position.

THEORY:
Linked List can be defined as collection of objects called nodes that are randomly stored
in the memory. A node contains two fields i.e. data stored at that particular address and
the pointer which contains the address of the next node in the memory. The last node of
the list contains pointer to the null.

ALGORITHM:

INSERT AT BEGINNING:
1. Declare a head pointer and make it as NULL.
2. Create a new node with the given data.
3. Make the new node points to the head node.
4. Finally, make the new node as the head node.
INSERT AT SPECIFIC POSITION:
• Traverse the Linked list upto position-1 nodes
• Once all the position-1 nodes are traversed, allocate memory and the given data
to the new node.
• Point the next pointer of the new node to the next of current node.
• Point the next pointer of current node to the new node

CODE:
#include <bits/stdc++.h>
using namespace std;
class node{
public:
int data;
node *next;
node(int data){
this->data = data;
this->next = NULL;
}
};
void insertathead(node *&head, int data){
node *temp = new node(data);
temp->next = head;
head = temp;
}
void insert_at_specific(int k, node *&head, int size, int data){
if (k > size){
cout << " not possible to insert" << endl;
}
else{
node *temp = head;
int i = 1;
while (i < k - 1){
temp = temp->next;
i++;
}
node *nn = new node(data);
node *tmp = temp->next;
temp->next = nn;
nn->next = tmp;
}
}
int sizell(node *head){
node *temp = head;
int count = 0;
while (temp != NULL){
count++;
temp = temp->next;
}
return count;
}
void printll(node *head){
node *temp = head;
while (temp != NULL){
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
int main(){
node *head = new node(6);
insertathead(head, 4);
insertathead(head, 2);
insertathead(head, 5);
cout << "linked list before insertion : "<<endl;
printll(head);
int size = sizell(head);
insert_at_specific(3, head, size, 7);
cout << endl;
cout << "linked list after inserting 7 at 3nd position : "<<endl;
printll(head);
cout<<endl;
cout << "linked list after inserting 1 at beginning : "<<endl;
insertathead(head, 1);
printll(head);
node *head1 = NULL;
node *head2 = NULL;
node *temp = head;
node *tail;
while (temp->next != NULL){
temp = temp->next;
}
tail = temp;
}

OUTPUT:
EXPERIMENT -16

AIM:
Write a C/C++ program to split a given linked list into two sub-list as Front sub-list and
Back sub-list, if odd number of the element then add the last element into the front list.

THEORY:
A linked list is a linear data structure, in which the elements are not stored at contiguous
memory locations. Linked List can be defined as collection of objects called nodes that
are randomly stored in the memory. A node contains two fields i.e. data stored at that
particular address and the pointer which contains the address of the next node in the
memory. The last node of the list contains pointer to the null.

CODE:
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
class node{
public:
int data;
node *next;
node(int data){
this->data = data;
this->next = NULL;
}
void insertathead(node *&head, int data){
node *temp = new node(data);
temp->next = head;
head = temp;
}
void print(node *&head){
node *temp = head;
while (temp != NULL){
cout << temp->data << "-> ";
temp = temp->next;
}
cout << "NULL" << endl;
}
int sizell(node *head){
node *temp = head;
int c = 0;
while (temp != NULL){
temp = temp->next;
c++;
}
return c;
}};
int main(){
node *head = new node(8);
head->insertathead(head, 5);
head->insertathead(head, 4);
head->insertathead(head, 2);
head->insertathead(head, 1);
head->print(head);
int y = head->sizell(head);
cout << endl;
node *head1 = NULL;
node *head2 = NULL;
int x = 0;
node *temp = head;
node *t1;
node *t2;
while (temp != NULL && x < y){
if (y % 2 == 1 && x == y - 1)
break;
if (x < y / 2){
if (head1 == NULL){
head1 = new node(temp->data);
t1 = head1;
x++;
temp = temp->next;
}
else{
node *newnode = new node(temp->data);
t1->next = newnode;
t1 = t1->next;
x++;
temp = temp->next;
}}
else if (x >= y / 2){
if (head2 == NULL){
head2 = new node(temp->data);
t2 = head2;
x++;
temp = temp->next;
}
else{
node *newnode = new node(temp->data);
t2->next = newnode;
t2 = t2->next;
temp = temp->next;
x++;
}}}
if (y == 1){
head1 = new node(temp->data);
exit(0);
}
if (y % 2 == 1)
t1->next = temp;
head1->print(head1);
head2->print(head2);
}

OUTPUT:
EXPERIMENT -17

AIM:
Given a Sorted doubly linked list of positive integers and an integer, finds all the pairs
(sum of two nodes data part) that is equal to the given integer value. Example: Double
Linked List 2, 5, 7, 8, 9, 10, 12, 16, 19, 25, and P=35 then pairs will be Pairs will be (10,
25), (16, 19).

THEORY:
Doubly linked list is a complex type of linked list in which a node contains a pointer to
the previous as well as the next node in the sequence. Therefore, in a doubly linked list,
a node consists of three parts: node data, pointer to the next node in sequence (next
pointer) , pointer to the previous node (previous pointer).
Example: Input : head : 1 <-> 2 <-> 4 <-> 5 <-> 6 <-> 8 <-> 9 x = 7
Output: (6, 1), (5,2)

ALGORITHM:
• Initialize two pointer variables to find the candidate elements in the sorted doubly
linked list. Initialize first with the start of the doubly linked list i.e; first=head and
initialize second with the last node of the doubly linked list i.e; second=last_node
• . • We initialize first and second pointers as first and last nodes. Here we don’t
have random access, so to find the second pointer, we traverse the list to
initialize the second.
• If current sum of first and second is less than x, then we move first in forward
direction. If current sum of first and second element is greater than x, then we
move second in backward direction.
• Loop termination conditions are also different from arrays. The loop terminates
when two pointers cross each other (second->next = first), or they become the
same (first == second).
• The case when no pairs are present will be handled by the condition
“first==second”
CODE:
#include "bits/stdc++.h"
using namespace std;
class node
{
public:
int data;
node *prev;
node *next;
node(int data)
{
this->data = data;
prev = NULL;
next = NULL;
}
void insert(int data, node *&tail)
{
node *x = new node(data);
tail->next = x;
x->prev = tail;
tail = x;
}
void print(node *head)
{
node *temp = head;
while (temp != NULL)
{
cout << temp->data << " ->";
temp = temp->next;
}
cout << "NULL" << endl;
}
void pairswithgivensum(node *head,vector<pair<int, int>> &ans, int k)
{
int i, j;
node *temp = head;
while (temp != NULL)
{
node *t = temp->next;
while (t != NULL){
if (t->data + temp->data == k)
ans.push_back({temp->data, t->data});
t = t->next;
}
temp = temp->next;
}
}
};
int main()
{
node *head = new node(1);
node *tail = head;
head->insert(2, tail);
head->insert(3, tail);
head->insert(4, tail);
head->print(head);
vector<pair<int, int>> ans;
head->pairswithgivensum(head, ans, 5);
int i;
if (ans.size() == 0)
cout << "no such pair exists" << endl;
cout << " Pairs with sum = 5 are " << endl;
for (i = 0; i < ans.size(); i++){
cout << ans[i].first << " " << ans[i].second;
cout << endl;
}
}

OUTPUT:
EXPERIMENT -18

AIM:
Write a C/C++ program to implement Stack Data Structure using Queue.

THEORY:
Given a Queue data structure that supports standard operations like enqueue() and
dequeue(). The task is to implement a Stack data structure using only instances of
Queue and Queue operations allowed on the instances. A Stack can be implemented
using two queues. Let Stack to be implemented be ‘s’ and queues used to implement
are ‘q1’ and ‘q2’. The idea is to keep newly entered element at the front of ‘q1’ so that
pop operation dequeues from ‘q1’. ‘q2’ is used to put every new element in front of ‘q1’.

ALGORITHM:
• Follow the below steps to implement the push(s, x) operation:
1. Enqueue x to q2.
2. One by one dequeue everything from q1 and enqueue to q2.
3. Swap the queues of q1 and q2.

• Follow the below steps to implement the pop(s) operation:


1. Dequeue an item from q1 and return it.

CODE:
#include <bits/stdc++.h>
using namespace std;
class Stack{
queue<int> q1, q2;
public:
void push(int x){
q2.push(x);
while (!q1.empty()){
q2.push(q1.front());
q1.pop();
}
queue<int> q = q1;
q1 = q2;
q2 = q;
}
void pop(){
if (q1.empty())
return;
q1.pop();
}
int top(){
if (q1.empty())
return -1;
return q1.front();
}
int size() { return q1.size(); }
};
int main(){
Stack s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
cout << "current size: " << s.size() << endl;
cout << s.top() << endl;
s.pop();
cout << s.top() << endl;
s.pop();
cout << s.top() << endl;
cout << "current size: " << s.size() << endl;
return 0;
}

OUTPUT:
EXPERIMENT -19

AIM:
Write a C/C++ program to implement Queue Data Structure using Stack.

THEORY:
Queue is a linear data structure that follows FIFO (First In First Out) principle in which
insertion is performed from the rear end and the deletion is done from the front end.
Stack is a linear data structure that follows LIFO (Last In First Out) principle in which
both insertion and deletion are performed from the top of the stack.

ALGORITHM:
enQueue(q, x):
• While stack1 is not empty, push everything from stack1 to stack2.
• Push x to stack1 (assuming size of stacks is unlimited).
• Push everything back to stack1.
deQueue(q):
• If stack1 is empty then error
• Pop an item from stack1 and return it

CODE:
#include <bits/stdc++.h>
using namespace std;
struct Queue{
stack<int> s1, s2;
void enQueue(int x)
{
while (!s1.empty())
{
s2.push(s1.top());
s1.pop();
}
s1.push(x);
while (!s2.empty())
{
s1.push(s2.top());
s2.pop();
}
}
int deQueue()
{
if (s1.empty())
{
cout << "Q is Empty";
exit(0);
}
int x = s1.top();
s1.pop();
return x;
}
};
int main()
{
Queue q;
q.enQueue(4);
q.enQueue(2);
q.enQueue(6);
q.enQueue(8);
cout << q.deQueue() << '\n';
cout << q.deQueue() << '\n';
cout << q.deQueue() << '\n';
cout << q.deQueue() << '\n';
return 0;}

OUTPUT:
EXPERIMENT -20

AIM:
Write a C/C++ program to implement the Binary Tree using linked list and perform In-
order traversal.

THEORY:
Binary Tree: A tree whose elements have at most 2 children is called a binary tree.
Since each element in a binary tree can have only 2 children, we typically name them
the left and right child.
Binary Tree Representation: A tree is represented by a pointer to the topmost node of
the tree. If the tree is empty, then the value of the root is NULL.
A Tree node contains the following parts.
1. Data
2. Pointer to the left child
3. Pointer to the right child

Inorder Traversal: If we want to traverse the nodes in ascending order, then we use
the inorder traversal. Following are the steps required for the inorder traversal:
• Visit all the nodes in the left subtree
• Visit the root node
• Visit all the nodes in the right subtree

ALGORITHM:
Inorder Traversal algorithm:
Until all nodes are traversed –
1Recursively traverse left subtree.
2Visit root node.
3Recursively traverse right subtree.

CODE:
#include "bits/stdc++.h"
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
void inorderTraversal(TreeNode* root)
{
if(root==NULL)
return ;
inorderTraversal(root-> left);
cout<<root->val<<" ";
inorderTraversal(root->right);
}
int main()
{
TreeNode *root= new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(7);
/*
Given Tree
1
/ \
2 3
/ \ /\
4 5 6 7
*/
cout<<"\nINORDER TRAVERSAL:";
inorderTraversal(root);
return 0;
}

OUTPUT:
EXPERIMENT -21

AIM:
Write a C/C++ program to check whether the given tree is a Binary Search Tree or not.

THEORY:
Binary search tree is a data structure that quickly allows us to maintain a sorted list of
numbers.
• It is called a binary tree because each tree node has a maximum of two children.
• It is called a search tree because it can be used to search for the presence of a
number in O(log(n)) time.

The properties that separate a binary search tree from a regular binary tree is
1. All nodes of left subtree are less than the root node
2. All nodes of right subtree are more than the root node
3. Both subtrees of each node are also BSTs i.e. they have the above two
properties

ALGORTHM:
Call the isValidBST function for the root node and set the minNode pointer as NULL
(representing -ve infinte) and the maxNode pointer as NULL(representing +ve infinte)
1. If the current node is NULL then return true
2. If the value of the node is less than the minimum value possible or greater than
the maximum value possible then return false
3. Call the same function for the left and the right subtree and narrow down the
minimum and maximum values for these calls accordingly
CODE:
#include "bits/stdc++.h"
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
bool isValidBST(TreeNode* root, TreeNode* minNode, TreeNode* maxNode)
{
if(!root) return true;
if(minNode && root->val <= minNode->val || maxNode && root->val >=
maxNode->val)
return false;
return isValidBST(root->left, minNode, root) && isValidBST(root->right, root, maxNode);
}
bool isValidBST(TreeNode* root)
{
return isValidBST(root, NULL, NULL);
}
int main()
{
TreeNode *root= new TreeNode(1);
root->left=new TreeNode(2);
root->right=new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
root->right->left = new TreeNode(6);
root->right->right = new TreeNode(7);
/*
Given Tree
1
/\
23
/\/\
4567
*/

if(isValidBST(root))
cout<<"GIVEN TREE IS A BST"<<endl;

else
cout<<"GIVEN TREE IS NOT A BST"<<endl;
TreeNode *root2= new TreeNode(4);
root2->left=new TreeNode(2);
root2->right=new TreeNode(6);
root2->left->left = new TreeNode(1);
root2->left->right = new TreeNode(3);
root2->right->left = new TreeNode(5);
root2->right->right = new TreeNode(7);
/*
Given Tree
4
/\
26
/\/\
1357
*/
if(isValidBST(root2))
cout<<"GIVEN TREE IS A BST"<<endl;
else
cout<<"GIVEN TREE IS NOT A BST"<<endl;
return 0;
}

OUTPUT:
EXPERIMENT -22

AIM:
Write a C/C++ program to implement insertion in the AVL tree.

THEORY:
AVL Tree can be defined as height balanced binary search tree in which each node is
associated with a balance factor which is calculated by subtracting the height of its right
sub-tree from that of its left sub-tree.
Tree is said to be balanced if balance factor of each node is in between -1 to 1,
otherwise, the tree will be unbalanced and need to be balanced.

Insertion in AVL tree is performed in the same way as it is performed in a binary search
tree. The new node is added into AVL tree as the leaf node. However, it may lead to
violation in the AVL tree property and therefore the tree may need balancing. The tree
can be balanced by applying rotations. Rotation is required only if, the balance factor of
any node is disturbed upon inserting the new node, otherwise the rotation is not
required. Depending upon the type of insertion, the Rotations are categorized into four
categories.
1. 1 LL Rotation: The new node is inserted to the left sub-tree of left sub-tree of
critical node.
2. 2 RR Rotation: The new node is inserted to the right sub-tree of the right sub-tree
of the critical node.
3. 3 LR Rotation: The new node is inserted to the right sub-tree of the left sub-tree
of the critical node.
4. 4 RL Rotation : The new node is inserted to the left sub tree of the right sub-tree
of the critical node.

CODE:
#include <bits/stdc++.h>
using namespace std;
class Node{
public:
int key;
Node *left;
Node *right;
int height;
};
int height(Node *N){
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b){
return (a > b) ? a : b;
}
Node *newNode(int key){
Node *node = new Node();
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
Node *rightRotate(Node *y){
Node *x = y->left;
Node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left),
height(y->right)) +1;
x->height = max(height(x->left),
height(x->right)) +1;
return x;
}
Node *leftRotate(Node *x){
Node *y = x->right;
Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left),
height(x->right)) +1;
y->height = max(height(y->left),
height(y->right)) +1;
return y;
}
int getBalance(Node *N){
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
Node *insert(Node *node, int key){
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else
return node;
node->height = 1 + max(height(node->left),
height(node->right));
int balance = getBalance(node);
if (balance > 1 && key < node->left->key)
return rightRotate(node);
if (balance < -1 && key > node->right->key)
return leftRotate(node);
if (balance > 1 && key > node->left->key){
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balance < -1 && key < node->right->key){
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
void preOrder(Node *root){
if (root != NULL){
cout << root->key << " ";
preOrder(root->left);
preOrder(root->right);
}}
int main(){
Node *root = NULL;
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);
/* The constructed AVL Tree would be
30
/\
20 40
/\\
10 25 50
*/
cout << "Preorder traversal of the constructed AVL tree is \n";
preOrder(root);
return 0;
}

OUTPUT:
EXPERIMENT -23

AIM:
Write a C/C++ program to Delete a key from the AVL tree.

THEORY:
AVL Tree can be defined as height balanced binary search tree in which each node is
associated with a balance factor which is calculated by subtracting the height of its right
sub-tree from that of its left sub tree.
Tree is said to be balanced if balance factor of each node is in between -1 to 1,
otherwise, the tree will be unbalanced and need to be balanced.

Deleting a node from an AVL tree is similar to that in a binary search tree. Deletion may
disturb the balance factor of an AVL tree and therefore the tree needs to be rebalanced
in order to maintain the AVLness. For this purpose, we need to perform rotations. The
two types of rotations are L rotation and R rotation. Here, we will discuss R rotations. L
rotations are the mirror images of them. If the node which is to be deleted is present in
the left sub-tree of the critical node, then L rotation needs to be applied else if, the node
which is to be deleted is present in the right sub-tree of the critical node, the R rotation
will be applied.

CODE:
#include <bits/stdc++.h>
using namespace std;
class Node{
public:
int key;
Node *left;
Node *right;
int height;
};
int max(int a, int b);
int height(Node *N)
{
if (N == NULL)
return 0;
return N->height;
}
int max(int a, int b){
return (a > b) ? a : b;
}
Node *newNode(int key)
{
Node *node = new Node();
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}
Node *rightRotate(Node *y)
{
Node *x = y->left;
Node *T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left),
height(y->right)) +1;
x->height = max(height(x->left),
height(x->right)) +1;
return x;
}
Node *leftRotate(Node *x)
{
Node *y = x->right;
Node *T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left),
height(x->right)) +1;
y->height = max(height(y->left),
height(y->right)) +1;
return y;
}
int getBalance(Node *N)
{
if (N == NULL)
return 0;
return height(N->left)-height(N->right);
}
Node *insert(Node *node, int key)
{
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else
return node;
node->height = 1 + max(height(node->left),
height(node->right));
int balance = getBalance(node);
if (balance > 1 && key < node->left->key)
return rightRotate(node);
if (balance < -1 && key > node->right->key)
return leftRotate(node);
if (balance > 1 && key > node->left->key){
node->left = leftRotate(node->left);
return rightRotate(node);
}
if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}
return node;
}
Node *minValueNode(Node *node)
{
Node *current = node;
while (current->left != NULL)
current = current->left;
return current;
}
Node *deleteNode(Node *root, int key){
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else{
if ((root->left == NULL)||(root->right == NULL)){
Node *temp = root->left ? root->left : root->right;
if (temp == NULL){
temp = root;
root = NULL;
}
else
*root = *temp;
free(temp);
}
else{
Node *temp = minValueNode(root->right);
root->key = temp->key;
root->right = deleteNode(root->right,
temp->key);
}}
if (root == NULL)
return root;
root->height = 1 + max(height(root->left),
height(root->right));
int balance = getBalance(root);
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
if (balance > 1 && getBalance(root->left) < 0){
root->left = leftRotate(root->left);
return rightRotate(root);
}
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
if (balance < -1 && getBalance(root->right) > 0){
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
void preOrder(Node *root){
if (root != NULL){
cout << root->key << " ";
preOrder(root->left);
preOrder(root->right);
}}
int main(){
Node *root = NULL;
/* Constructing tree given in
the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 0);
root = insert(root, 6);
root = insert(root, 11);
root = insert(root, -1);
root = insert(root, 1);
root = insert(root, 2);
/* The constructed AVL Tree would be
9
/\
1 10
/\\
0 5 11
//\
-1 2 6
*/
cout << "Preorder traversal of the constructed AVL tree is \n";
preOrder(root);
root = deleteNode(root, 10);
/* The AVL Tree after deletion of 10
1
/\
09
//\
-1 5 11
/\
26
*/
cout << "\nPreorder traversal after deletion of 10 \n";
preOrder(root);
return 0;
}

OUTPUT:
EXPERIMENT -24

AIM:
Write a C/C++ program to count the number of leaf nodes in an AVL tree.

THEORY:

AVL Tree can be defined as height balanced binary search tree in which each node is
associated with a balance factor which is calculated by subtracting the height of its right
sub-tree from that of its left sub tree.

Tree is said to be balanced if balance factor of each node is in between -1 to 1,


otherwise, the tree will be unbalanced and need to be balanced

CODE:
#include <bits/stdc++.h>
using namespace std;
struct node
{
int data;
struct node *left;
struct node *right;
};
unsigned int getLeafCount(struct node *node){
if (node == NULL)
return 0;
if (node->left == NULL && node->right == NULL)
return 1;
else
return getLeafCount(node->left) +getLeafCount(node->right);
}
struct node *newNode(int data){
struct node *node = (struct node *)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return (node);
}

int main()
{
struct node *root = newNode(5);

root->left = newNode(2);
root->right = newNode(9);
root->left->left = newNode(1);
root->left->right = newNode(4);
root->right->left = newNode(7);
root->right->right = newNode(11);

/* GIVEN AVL TREE


5
/\
29
/\/\
1 4 7 11
*/

cout << "Leaf count of the AVL tree is : " << getLeafCount(root) << endl;
return 0;
}

OUTPUT:

You might also like