DS Unit-2 Datastructures
DS Unit-2 Datastructures
• Non linear data structures are the data structures in which data
may be arranged in a hierarchial manner.
LIST ADT
List is basically the collection of elements arranged in a
sequential manner. In memory we can store the list in two
ways:
•One way is we can store the elements in sequential memory
locations. That means we can store the list in arrays.
The main advantage of a doubly linked list is that, they permit traversing or
searching of the list in both directions.
In this linked list each node contains three fields. a) One to store data
b) Remaining are self referential pointers which points to previous and next
nodes in the list .
/*
Class Declaration
*/
2. Write a program to perform the
class double_llist
following operations on doubly linked {
list: public:
i) Creation ii) Insertion iii) Deletion iv) void create_list(int value);
Traversal v) Print the list in reverse void add_begin(int value);
#include<iostream> void add_after(int value, int position);
#include<cstdio> void delete_element(int value);
#include<cstdlib>
void display_dlist();
using namespace std;
/*
void reverse();
•Node Declaration double_llist()
*/ {
struct node
{ start = NULL;
int info; }
struct node *next; };
struct node *prev;
}*start;
/*
•Main: Contains Menu
case 2:
*/
cout<<"Enter the element: ";
int main() cin>>element;
dl.add_begin(element);
{
cout<<endl;
int choice, element, position; break;
double_llist dl;
case 3:
while (1) cout<<"Enter the element: ";
cin>>element;
{
cout<<"Insert Element after postion: ";
cout<<endl<<" "<<endl;
cin>>position;
cout<<endl<<"Operations on Doubly linked list"<<endl;
dl.add_after(element, position);
cout<<endl<<" "<<endl;
cout<<endl;
cout<<"1.Create Node"<<endl;
break;
cout<<"2.Add at begining"<<endl;
cout<<"3.Add after position"<<endl;
case 4:
cout<<"4.Delete"<<endl;
if (start == NULL)
cout<<"5.Traverse"<<endl;
{
cout<<"6.Reverse"<<endl;
cout<<"List empty,nothing to delete"<<endl;
cout<<"7.Quit"<<endl;
break;
cout<<"Enter your choice : ";
}
cin>>choice;
cout<<"Enter the element for deletion: ";
switch ( choice )
cin>>element;
{
dl.delete_element(element);
case 1:
cout<<endl;
cout<<"Enter the element: ";
break;
cin>>element;
dl.create_list(element);
cout<<endl;
break;
case 5:
dl.display_dlist();
cout<<endl;
break;
case 6:
if (start == NULL)
{
cout<<"List empty,nothing to reverse"<<endl;
break;
}
dl.reverse();
cout<<endl;
break;
case 7:
exit(1);
default:
cout<<"Wrong choice"<<endl;
}
}
return 0;
}
/*
•Create Double Link List
*/
void double_llist::create_list(int value)
{
struct node *s, *temp;
temp = new(struct node);
temp->info = value;
temp->next = NULL;
if (start == NULL)
{
temp->prev = NULL;
start = temp;
}
else
{
s = start;
while (s->next != NULL)
s = s->next;
s->next = temp;
temp->prev = s;
}
}
/*
•Insertion at the beginning
*/
void double_llist::add_begin(int value)
{
if (start == NULL)
{
cout<<"First Create the list."<<endl;
return;
}
struct node *temp;
temp = new(struct node);
temp->prev = NULL;
temp->info = value;
temp->next = start;
start->prev = temp;
start = temp;
cout<<"Element Inserted"<<endl;
/* if (q->next == NULL)
•Insertion of element at a particular position {
*/ q->next = tmp;
void double_llist::add_after(int value, int pos) tmp->next = NULL;
{ tmp->prev = q;
if (start == NULL) }
{ else
cout<<"First Create the list."<<endl; {
return; tmp->next = q->next;
} tmp->next->prev = tmp;
struct node *tmp, *q; int i; q->next = tmp;
q = start; tmp->prev = q;
for (i = 0;i<pos - 1;i++) }
{ cout<<"Element Inserted"<<endl;
q = q->next; }
if (q == NULL)
{
cout<<"There are less than ";
cout<<pos<<" elements."<<endl;
return;
}
}
tmp = new(struct node);
tmp->info = value;
/* while (q->next->next != NULL)
•Deletion of element from the list {
*/ /*Element deleted in between*/
void double_llist::delete_element(int value) if (q->next->info == value)
{ {
struct node *tmp, *q; tmp = q->next;
/*first element deletion*/ q->next = tmp->next;
if (start->info == value) tmp->next->prev = q;
{ cout<<"Element Deleted"<<endl; free(tmp);
return;
tmp = start;
}
start = start->next; q = q->next;
start->prev = NULL; }
cout<<"Element Deleted"<<endl; /*last element deleted*/
free(tmp); if (q->next->info == value)
return; {
} tmp = q->next;
q = start; free(tmp);
q->next = NULL;
cout<<"Element Deleted"<<endl;
return;
}
cout<<"Element "<<value<<" not
found"<<endl;
}
/*
•Reverse Doubly Link List
*/
void double_llist::reverse()
{
struct node *p1, *p2;
p1 = start;
p2 = p1->next;
p1->next = NULL;
p1->prev = p2;
while (p2 != NULL)
{
p2->prev = p2->next; // old value of next of p2 is assigned to current value of prev of
p2
p2->next = p1;
p1 = p2;
p2 = p2->prev;
}
start = p1;
cout<<"List Reversed"<<endl;
}
/*
* Display elements of Doubly Link List
*/
void double_llist::display_dlist()
{
struct node *q;
if (start == NULL)
{
cout<<"List empty,nothing to display"<<endl;
return;
}
q = start;
cout<<"The Doubly Link List is :"<<endl;
while (q != NULL)
{
cout<<q->info<<" <-> ";
q = q->next;
}
cout<<"NULL"<<endl;
}
3. Write a program to perform the following
operations on circular linkedlist.:
i) Creation ii) Insertion iii) Deletion iv) /*
Traversal v) Count of nodes * Class Declaration
#include<iostream> */
#include<cstdio> class circular_llist
#include<cstdlib> {
using namespace std; public:
/* void create_node(int value);
* Node Declaration void add_begin(int value);
*/ void add_after(int value, int position);
struct node void delete_element(int value);
{ void display_list();
int info; int count();
struct node *next;
}*last; circular_llist()
{
last = NULL;
}
};
/*
* Main :contains menu
*/
int main()
{
int choice, element, position;
circular_llist cl;
while (1)
{
cout<<endl<<" "<<endl;
cout<<endl<<"Circular singly linked list"<<endl;
cout<<endl<<" "<<endl;
cout<<"1.Create Node"<<endl;
cout<<"2.Add at beginning"<<endl;
cout<<"3.Add after"<<endl;
cout<<"4.Delete"<<endl;
cout<<"5.Display"<<endl;
cout<<"6.Count"<<endl;
cout<<"7.Quit"<<endl;
cout<<"Enter your choice : ";
cin>>choice;
switch(choice)
case 4:
{
if (last == NULL)
case 1:
{
cout<<"Enter the element: ";
cout<<"List is empty, nothing to
cin>>element;
delete"<<endl; break;
cl.create_node(element);
}
cout<<endl;
cout<<"Enter the element for deletion: ";
break;
cin>>element;
case 2:
cl.delete_element(element);
cout<<"Enter the element: ";
cout<<endl;
cin>>element;
break;
cl.add_begin(element);
case 5:
cout<<endl;
cl.display_list();
break;
break;
case 3:
case 6:
cout<<"Enter the element: ";
cout<<"Count of Nodes= "<<cl.count()<<endl;
cin>>element;
break;
cout<<"Insert element after position: ";
case 7:
cin>>position;
exit(1);
cl.add_after(element, position);
break;
cout<<endl;
default:
break;
cout<<"Wrong choice"<<endl;
}}
return 0;
}
/*
* Create Circular Link List
*/
void circular_llist::create_node(int value)
{
struct node *temp;
temp = new(struct node);
temp->info = value;
if (last == NULL)
{
last = temp;
temp->next = last;
}
else
{
temp->next = last->next;
last->next = temp;
last = temp;
}
}
/*
* Insertion of element at beginning
*/
void circular_llist::add_begin(int value)
{
if (last == NULL)
{
cout<<"First Create the list."<<endl;
return;
}
struct node *temp;
temp = new(struct node);
temp->info = value;
temp->next = last->next;
last->next = temp;
}
/*
* Insertion of element at a particular place
*/
void circular_llist::add_after(int value, int pos)
{
if (last == NULL)
{ temp = new(struct node);
cout<<"First Create the list."<<endl; temp->next = s->next;
return; temp->info = value;
} s->next = temp;
struct node *temp, *s;
/*Element inserted at the end*/
s = last->next;
if (s == last)
for (int i = 0;i< pos-1;i++)
{
{
last=temp;
s = s->next;
}
if (s == last->next)
}
{
cout<<"There are less than ";
cout<<pos<<" in the list"<<endl;
return;
}
}
while (s->next != last)
{
/* /*Deletion of Element in between*/
* Deletion of element from the list if (s->next->info == value)
*/ {
void circular_llist::delete_element(int value) temp = s->next;
{ s->next = temp->next;
struct node *temp, *s; free(temp);
s = last->next; cout<<"Element "<<value;
/* If List has only one element*/ cout<<" deleted from the list"<<endl;
if (last->next == last && last->info == value) return;
{ }
temp = last; s = s->next;
last = NULL;
}
free(temp);
return;
}
if (s->info == value) /*First Element Deletion*/
{
temp = s;
last->next = s->next;
free(temp);
return;
}
/*Deletion of last element*/
if (s->next->info == value)
{
temp = s->next;
s->next = last->next;
free(temp);
last = s;
return;
}
cout<<"Element "<<value<<" not found in the
list"<<endl;
}
/*
* Display Circular Link List
*/
void circular_llist::display_list()
{
struct node *s;
if (last == NULL)
{
cout<<"List is empty, nothing to display"<<endl;
return;
}
s = last->next;
cout<<"Circular Link List: "<<endl;
do
{
cout<<s->info<<"->";
s = s->next;
} while (s != last->next);
if(s==last->next)
cout<<s->info<<endl;
}
int circular_llist::count()
{
int count=0;
struct node *s;
if (last == NULL)
{
cout<<"List is empty, nothing to
display"<<endl;
return 0;
}
s = last->next;
while (s != last)
{
count++;
s = s->next;
}
count++;
return count;
}
STACK
STACK ADT
cin>>data;
stk[top]=data;
cout<<"Pushed Successfully....\n";
}
}
Popping an element from stack:
To remove an item, first extract the data from top position in
the stack and then decrement the stack pointer, top.
4.a.(i). Write a program that implement stack (its operations) using Arrays
#include <iostream> void pop()
using namespace std; {
-
int stack[100], max=100, top= 1; -
if(top<= 1)
cout<<"Stack Underflow"<<endl;
void push(int val) else
{ {
if(top>=max-1) cout<<"The popped element is "<< stack[top] <<endl;
cout<<"Stack Overflow"<<endl; top--;
else }
{ }
top++; void display()
{
stack[top]=val; if(top>=0)
} {
} cout<<"Stack elements are:";
for(int i=top; i>=0; i--)
cout<<stack[i]<<" ";
cout<<endl;
}
else
cout<<"Stack is empty";
}
int main() case 2:
{ pop();
break;
int ch, val;
cout<<"1) Push in stack"<<endl; case 3: display();
cout<<"2) Pop from stack"<<endl; break;
cout<<"3) Display stack"<<endl;
cout<<"4) Exit"<<endl; case 4: cout<<"Exit"<<endl;
do break;
{
cout<<"Enter choice: "<<endl; default:
cin>>ch; cout<<"Invalid Choice"<<endl;
switch(ch) }
{ }while(ch!=4);
case 1:
cout<<"Enter value to be return 0;
pushed:"<<endl; }
cin>>val;
push(val);
break;
4.a.(ii). Write a program that implement stack (its operations) using Linkedlists.
#include <iostream>
#include<stdlib.h>
using namespace std;
struct Node
{
int data;
struct Node *next;
};
struct Node* top = NULL;
void push(int val)
{
struct Node* newnode = (struct Node*) malloc(sizeof(struct Node));
newnode->data = val;
newnode->next = top;
top = newnode;
}
void pop()
{
if(top==NULL)
cout<<"Stack Underflow"<<endl;
else
{
cout<<"The popped element is "<< top->data <<endl;
top = top->next;
}
}
void display()
{
struct Node* ptr;
if(top==NULL)
cout<<"stack is empty";
else
{
ptr = top;
cout<<"Stack elements are: ";
while (ptr != NULL)
{
cout<<ptr->data <<" ";
ptr = ptr->next;
}
}
cout<<endl;
}
int main() case 3:
{ display();
int ch, val;
cout<<"1) Push in stack"<<endl;
break;
cout<<"2) Pop from stack"<<endl;
cout<<"3) Display stack"<<endl; case 4:
cout<<"4) Exit"<<endl; cout<<"Exit"<<endl;
do break;
{
cout<<"Enter choice: "<<endl;
cin>>ch; default:
switch(ch) cout<<"Invalid Choice"<<endl;
{ }
case 1: }while(ch!=4);
cout<<"Enter value to be pushed:"<<endl;
cin>>val;
return 0;
push(val); }
break;
case 2:
pop();
break;
INFIX TO POSTFIX CONVERSION USING STACKS
Basic:-
Infix Expression: The operator is in between the
two operands
Example: A + B is known as infix expression.
Postfix Expression: The operator is after the two
operands
Example: BD + is known as postfix expression.
Steps needed for infix to postfix conversion using stack in C++:-
1. First Start scanning the expression from left to right
2. If the scanned character is an operand, output it, i.e. print it
3. Else
• If the precedence of the scanned operator is higher than the
precedence of the operator in the stack(or stack is empty or has'(‘),
then push operator in the stack
• Else, Pop all the operators, that have greater or equal precedence than
the scanned operator. Once you pop them push this scanned operator.
(If we see a parenthesis while popping then stop and push scanned
operator in the stack)
4. If the scanned character is an ‘(‘, push it to the stack.
5. If the scanned character is an ‘)’, pop the stack and output it until a ‘(‘ is
encountered, and discard both the parenthesis.
6. Now, we should repeat steps 2 – 6 until the whole infix i.e. whole
characters are scanned.
7. Print output
8. Do the pop and output (print) until the stack is not empty
Benefits of Postfix expression over infix expression
•In postfix any formula can be expressed without
parenthesis.
•It is very useful for evaluating formulas on
computers with stacks.
•Infix operators have precedence
4. b. Write a program to implement Infix to Postfix Conversion using Stacks
#include<iostream>
#include<string.h> infix :: infix( )
#include<ctype.h>
using namespace std;
{
const int MAX = 50 ; top = -1 ;
class infix strcpy( target, "" ) ;
{ strcpy( stack, "" ) ;
private : t = target ;
char target[MAX], stack[MAX] ;
char *s, *t ;
s = "" ;
int top ; }
public :
infix( ) ;
void setexpr( char *str ) ;
void push ( char c ) ;
char pop( ) ;
void convert( ) ;
int priority ( char c ) ;
void show( ) ;
};
void infix :: setexpr ( char *str )
{
s = str ; else
} {
void infix :: push ( char c ) char item = stack[top] ;
{ top-- ;
if ( top == MAX ) return item ;
cout<< "\nStack is full\n" ;
else }
{ }
top++ ;
stack[top] = c ;
}
}
char infix :: pop( )
{
if ( top == -1 )
{
cout<< "\nStack is empty\n" ;
return -1 ;
}
void infix :: convert( )
{ if ( *s == '(' )
while ( *s )
{ {
if ( *s == ' ' || *s == '\t' ) push ( *s ) ;
{
s++ ;
s++ ;
continue ; }
}
if ( isdigit ( *s ) || isalpha ( *s ) )
{
while ( isdigit ( *s ) || isalpha ( *s ) )
{
*t = *s ;
s++ ;
t++ ;
}
}
char opr ;
if ( *s == '*' || *s == '+' || *s == '/' || *s == '%' || *s == '-' || *s == '$' )
{
if ( top != -1 )
{
opr = pop( ) ;
while ( priority ( opr ) >= priority ( *s ) )
{
*t = opr ;
t++ ;
opr = pop( ) ;
}
push ( opr ) ;
push ( *s ) ;
}
else
push ( *s ) ;
s++ ;
}
if ( *s == ')' ) int infix :: priority ( char c )
{ {
opr = pop( ) ;
while ( (opr ) != '(' )
if ( c == '$' )
{ return 3 ;
*t = opr ; if ( c == '*' || c == '/' || c == '%' )
t++ ; return 2 ;
opr = pop( ) ; else
}
s++ ;
{
} if ( c == '+' || c == '-' )
} return 1 ;
while ( top != -1 ) else
{ return 0 ;
char opr = pop( ) ;
*t = opr ;
}
t++ ; }
} void infix :: show( )
*t = '\0' ; {
} cout<<target ;
}
int main( )
{
char expr[MAX] ;
infix q ;
cout<< "\nEnter an expression in infix form: " ;
cin.getline ( expr, MAX ) ;//getline() is a standard library function to
read // string or line from an input stream,it is a part of string header.
q.setexpr ( expr ) ;
q.convert( ) ;
cout<< "\nThe postfix expression is: " ;
q.show( ) ;
return 0;
}
EVALUATION OF POSTFIX EXPRESSION
1. Start reading the expression from left to right.
2. If the element is an operand then, push it in the stack.
3. If the element is an operator, then pop two elements
from the stack and use the operator on them.
4. Push the result of the operation back into the stack
after calculation.
5. Keep repeating the above steps until the end of the
expression is reached.
6. The final result will be now left in the stack, display
the same.
#include<iostream>
#include<stack>
#include<math.h>
using namespace std;
// The function calculate_Postfix returns the final answer of the expression after
calculation
int calculate_Postfix(string post_exp)
{
stack <int> stack;
int len = post_exp.length();
// loop to iterate through the expression
for (int i = 0; i < len; i++)
{
// if the character is an operand we push it in the stack
// we have considered single digits only here
if ( post_exp[i] >= '0' && post_exp[i] <= '9')
{
stack.push( post_exp[i] - '0');
}
// if the character is an operator we enter else block
else case '/': // division
{ stack.push(b / a);
// we pop the top two elements from the break;
stack and save them in two integers case '^': // exponent
int a = stack.top(); stack.push(pow(b,a));
stack.pop(); break;
int b = stack.top(); }
stack.pop(); }
//performing the operation on the operands }
switch (post_exp[i]) //returning the calculated result
{ return stack.top();
case '+': // addition }
stack.push(b + a); //main function/ driver function
break; int main()
case '-': // subtraction {
stack.push(b - a); //we save the postfix expression to calculate
break; in postfix_expression string
case '*': // multiplication string postfix_expression = "59+33^4*6/-";
stack.push(b * a); cout<<"The answer after calculating the postfix
break; expression is : ";
cout<<calculate_Postfix(postfix_expression);
return 0;
}
Output
The answer after calculating the postfix expression is: -4
The objective of the puzzle is to move the entire stack to another rod,
obeying the following simple rules:
1.Only one disk can be moved at a time.
2.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.
3.No disk may be placed on top of a smaller disk.
QUEUE ADT
•The maximum queue size has to be set at compile time, rather than
at run time.
• Space can be wasted, if we do not use the full capacity of the array.
Operations on Queue: A queue have two basic operations:
a)adding new item to the queue
b) removing items from queue.
while(1)
{
cout<<"\n\n*****Menu for QUEUE operations*****\n\n";
cout<<"1.INSERT\n2.DELETE\n3.DISPLAY\n4.EXIT\n";
cout<<"Enter Choice:";
cin>>choice;
switch(choice)
{
case 1:
q.insert_q();
break;
case 2:
q.delete_q();
break;
case 3:
cout<<"Elements in the queue are \n";
q.display_q();
break;
case 4:
exit(0);
default:
cout<<"Invalid choice...Try again...\n";
}
}
return 0;
}
5.a.(ii). Write a program that implement Queue (its operations) using LinkedLists
template <class T>
#include<stdlib.h> class queue
#include<iostream> {
using namespace std; private:
T item;
template <class T>
friend class node<T>;
class node node<T> *front,*rear;
{ public:
public: queue();
T data; void insert_q();
node<T>*next; void delete_q();
void display_q();
};
};
template <class T>
queue<T>::queue()
{
front=rear=NULL;
}
//code to push an item into queue;
template <class T>
void queue<T>::insert_q()
{
node<T>*p;
cout<<"Enter an element to be inserted:";
cin>>item;
p=new node<T>; else
p->data=item; {
p->next=NULL; rear->next=p;
if(front==NULL) rear=p;
{ }
rear=front=p; cout<<"\nInserted into Queue Succesfully\n";
} }
//code to delete an element
template <class T>
void queue<T>::delete_q()
{
node<T>*t;
if(front==NULL)
cout<<"\nqueue is Underflow";
else
{
item=front->data;
t=front;
front=front->next;
cout<<"\n"<<item<<" is deleted Successfully from queue \n";
}
delete(t);
}
//code to display elements in queue
template <class T>
void queue<T>::display_q()
{
node<T>*t;
if(front==NULL)
cout<<"\n queue Under Flow";
else
{
cout<<"\n Elements in the queue are \n";
t=front;
while(t!=NULL)
{
cout<<"|"<<t->data<<"|<-";
t=t->next;
}
}
}
switch(choice)
int main() {
{ case 1:
q1.insert_q();
int choice;
break;
queue<int>q1; case 2:
while(1) q1.delete_q();
{ break;
cout<<"\n\n***Menu for Queue case 3:
operations***\n\n"; q1.display_q();
break;
cout<<"1.Insert\n2.Delete\n case 4:
3.DISPLAY\n4.EXIT\n"; exit(0);
cout<<"Enter Choice:"; default:
cout<<"Invalid choice...Try again...\n";
cin>>choice;
}
}
return 0;
}
CIRCULAR QUEUE
Once the queue gets filled up, no more elements can be added to it
even if any element is removed from it consequently. This is because
during deletion, rear pointer is not adjusted
When the queue contains very few items and the rear pointer
points to last element. i.e. rear=maxSize-1, we cannot insert any
more items into queue because the overflow condition satisfies.
That means a lot of space is wasted.
Frequent reshuffling of elements is time consuming. One solution to
this is arranging all elements in a circular fashion. Such structures
are often referred to as Circular Queues.
To insert any element from front end then first shift all the
elements to the right.
// Function to insert data into stack
5.b. Write a program to void Stack::push(int x)
implement Queue using two stacks. {
# include<iostream> if(top >= 10)
{
using namespace std
// implementing the stack class cout<< "Stack Overflow \n";
}
class Stack
{ else
{
int top;
public: a[++top] = x;
cout<< "Element Inserted into Stack\n";
int a[10]; //Maximum size of Stack
}
Stack() }
{
top = -1;
}
// declaring all the function
void push(int x);
int pop();
bool isEmpty();
};
// Function to remove data from the top of the stack
int Stack::pop()
{ // Function to check if stack is empty
bool Stack::isEmpty()
if(top < 0)
{ {
cout<< "Stack Underflow \n"; if(top < 0)
return 0;
{
}
return true;
else
}
{ else
int d = a[top--];
{
return d;
} return false;
} }
}
//Implementing the queue class
class Queue
{
public:
Stack S1, S2;
//declaring enqueue method
void enqueue(int x);
//declaring dequeue method
int dequeue();
};
// Enqueue function