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

DS Unit-2 Datastructures

Uploaded by

pranava
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

DS Unit-2 Datastructures

Uploaded by

pranava
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 140

UNIT 2: DATA STRUCTURES

TOPICS: Introduction to linked lists, stacks, queues and


applications of stacks.
Data structure:
A data structure is a specialized format for organizing and storing
data.
General data structure types include the array, the file, the record, the
table, the tree, and so on.
Any data structure is designed to organize data to suit a specific purpose
so that it can be accessed and worked with in appropriate ways.
Abstract Data Type
In computer science, an abstract data type (ADT) is a
mathematical model for data types, where a data type is defined
by its behavior (semantics) from the point of view of a user of
the data, specifically in terms of possible values, possible
operations on data of this type, and the behavior of these
operations.
When a class is used as a type, it is an abstract type that refers to a
hidden representation.
In this model an ADT is typically implemented as a class, and each
instance of the ADT is usually an object of that class. In ADT all the
implementation details are hidden
• Linear data structures are the data structures in which data is
arranged in a list or in a sequence.

• 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 other way is we can use pointers or links to associate


elements sequentially. This is known as linked list.
LINKED LISTS
The linked list is very flexible dynamic data structure : items
may be added to it or deleted from it at will. A programmer
need not worry about how many items a program will have
to accommodate in advance. This allows us to write robust
programs which require much less maintenance.
The linked allocation has the following draw backs:
1. No direct access to a particular element.
2. Additional memory required for pointers.

Linked list are of 3 types:


3. Single Linked List
4. Double Linked List
5. Circular Linked List
SINGLE LINKED LIST
A single linked list, or simply a linked list, is a linear collection of data items. The
linear order is given by means of POINTERS. These types of lists are often referred
to as linear linked list.
•Each item in the list is called a node.
•* Each node of the list has two fields:
•1. Information- contains the item being stored in the list.
•2. Next address- contains the address of the next item in the list.
•* The last node in the list contains NULL pointer to indicate that it is the end of
the list.
•Conceptual view of Singly Linked List
Operations on Single linked list:
• Insertion of a node
• Deletions of a node
•Traversing the list
1. Write a program to perform the /*
following operations on singly linked * Class Declaration
list:
i) Creation ii) Insertion iii) Deletion iv)
*/
Traversal v) length of the linked list class single_llist
#include<iostream> {
#include<cstdio>
#include<cstdlib>
public:
using namespace std; node* create_node(int);
/* void insert_begin();
* Node Declaration void insert_pos();
*/
void insert_last();
struct node
void delete_pos();
{
void display();
int info;
int length_list();
struct node *next;
single_llist()
}*start; {
start = NULL;
}
};
main()
{
int choice, nodes, element, position, i;
single_llist sl;
start = NULL;
while (1)
{
cout<<endl<<" "<<endl;
cout<<endl<<"Operations on singly linked list"<<endl;
cout<<endl<<" "<<endl;
cout<<"1.Create node"<<endl;
cout<<"2.Insert Node at beginning"<<endl;
cout<<"3.Insert node at last"<<endl;
cout<<"4.Insert node at position"<<endl;
cout<<"5.Delete node at a position"<<endl;
cout<<"6.Display Linked List"<<endl;
cout<<"7.Length of the Linked List"<<endl;
cout<<"8.Exit "<<endl;
cout<<"Enter your choice : ";
cin>>choice;
switch(choice) case 5:
{ cout<<"Delete a particular node: "<<endl;
int val; sl.delete_pos();
case 1: cout<<endl;
cout<<"Creating a node: "<<endl; break;
cout<<"Enter a value:"<<endl; case 6:
cin>>val; cout<<"Display elements of linked
sl.create_node(val); list"<<endl;
cout<<endl; sl.display();
break; cout<<endl;
case 2: break;
cout<<"Inserting Node at Beginning: "<<endl; case 7:
sl.insert_begin(); cout<<"Length of the linked list =
cout<<endl; "<<sl.length_list()<<endl;
break; cout<<endl;
case 3: break;
cout<<"Inserting Node at Last: "<<endl; case 8: cout<<"Exiting..."<<endl;
sl.insert_last(); exit(1);
cout<<endl; break;
break; default:
case 4: cout<<"Wrong choice"<<endl;
cout<<"Inserting Node at a given position:"<<endl; }
sl.insert_pos(); }
cout<<endl; }
break;
/*
* Creating Node
*/
node *single_llist::create_node(int value)
{
struct node *temp, *s;
temp = new(struct node);
if (temp == NULL)
{
cout<<"Memory not allocated "<<endl; return 0;
}
else
{
temp->info = value;
temp->next = NULL;
cout<<"A node "<<temp->info<<" is created"<<endl;
return temp;
}
}
/*
* Inserting element in beginning
*/
void single_llist::insert_begin()
{
int value;
cout<<"Enter the value to be inserted: ";
cin>>value;
struct node *temp, *p;
temp = create_node(value);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
else
{
p = start;
start = temp;
start->next = p;
}
cout<<"Element Inserted at beginning"<<endl;
}
/*
* Inserting Node at last
*/
void single_llist::insert_last()
{
int value;
cout<<"Enter the value to be inserted: ";
cin>>value;

struct node *temp, *s;


temp = create_node(value);
s = start;
while (s->next != NULL)
{
s = s->next;
}
temp->next = NULL;
s->next = temp;
cout<<"Element Inserted at last"<<endl;
}
/* if (pos == 1)
* Insertion of node at a given position {
*/ if (start == NULL)
void single_llist::insert_pos() {
{ start = temp;
int value, pos, counter = 0; start->next = NULL;
cout<<"Enter the value to be inserted: "; }
cin>>value;
struct node *temp, *s, *ptr;
temp = create_node(value);
cout<<"Enter the postion at which node to be inserted: ";
cin>>pos;
int i;
s = start;
while (s != NULL)
{
s = s->next;
counter++;
}
else
{
ptr = start;
start = temp;
start->next = ptr;
}
}
else if (pos> 1 &&pos<= counter)
{
s = start;
for (i = 1; i<pos; i++)
{
ptr = s;
s = s->next;
}
ptr->next = temp;
temp->next = s;
}
else
{
cout<<"Positon out of range"<<endl;
}
}
/*
* Delete element at a given position
*/
void single_llist::delete_pos()
{
int pos, i, counter = 0;
if (start == NULL)
{
cout<<"List is empty"<<endl;
return;
}
cout<<"Enter the position of value to be deleted: ";
cin>>pos;
struct node *s, *ptr;
s = start;
if (pos == 1)
{
start = s->next;
}
else
{
while (s != NULL)
{
s = s->next;
counter++;
}
if (pos> 0 &&pos<= counter)
{
s = start;
for (i = 1;i<pos;i++)
{
ptr = s;
s = s->next;
}
ptr->next = s->next;
}
else
{
cout<<"Position out of range"<<endl;
}
free(s);
cout<<"Element Deleted"<<endl;
}
}
/*
* Display length of a link list
*/
int single_llist::length_list()
{
struct node *temp;
int count=0;
if (start == NULL)
{
cout<<"The List is Empty"<<endl;
return 0;
}
temp = start;
while (temp != NULL)
{
count++;
temp = temp->next;
}
return count;
}
/*
* Display Elements of a link list
*/
void single_llist::display()
{
struct node *temp;
if (start == NULL)
{
cout<<"The List is Empty"<<endl; return;
}
temp = start;
cout<<"Elements of list are: "<<endl;
while (temp != NULL)
{
cout<<temp->info<<"->";
temp = temp->next;
}
cout<<"NULL"<<endl;
}
DOUBLY LINKED LIST
A singly linked list has the disadvantage that we can only traverse it in one direction.
Many applications require searching backwards and forwards through sections of a
list. A useful refinement that can be made to the singly linked list is to create a doubly
linked list.
The distinction made between the two list types is that while singly linked list
have pointers going in one direction, doubly linked list have pointer both to the
next and to the previous element in the list.

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

•A Stack is a linear data structure where insertion and deletion of


items takes place at one end called top of the stack.

•A Stack is defined as a data structure which operates on a last-in


first-out basis. So it is also is referred as Last-in First-out( LIFO)-
an element inserted last will be removed first.

•Stack uses a single index or pointer to keep track of the information


in the stack.

•The basic operations associated with the stack are: a) push(insert) an


item onto the stack. b) pop(remove) an item from the stack.
The general terminology associated with the stack is as
follows:

A stack pointer keeps track of the current position on the stack.


When an element is placed on the stack, it is said to be pushed
on the stack.

When an object is removed from the stack, it is said to be


popped off the stack.

Two additional terms almost always used with stacks are


overflow- which occurs when we try to push more information
on a stack that it can hold, and underflow-which occurs when
we try to pop an item off a stack which is empty.
Pushing items onto the stack: Assume that the array
elements begin at 0
(because the array subscript starts from 0) and the
maximum elements that can be placed in stack is max.

The stack pointer, top, is considered to be pointing to


the top element of the stack.

A push operation thus involves adjusting the stack


pointer to point to next free slot and then copying
data into that slot of the stack.

Initially the top is initialized to -1.


//Code to push an element on to //Code to pop an element from a stack;
stack;
void stack::pop()
void stack::push() {
{ if(top==-1)
if(top==max-1) cout<<“stack underflow”;
else
cout<<"Stack Overflow...\n"; {
else cout<<“the elelment popped is:”<<stk[top];
{
top--;
cout<<"Enter an element to be
pushed:"; }
top++; }

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 working of the above code is as:

•Push ‘5’ and ‘9’ in the stack.


•Pop ‘5’ and ‘9’ from the stack, add them and then push ‘14’ in the stack.
•Push ‘3’ and ‘3’ in the stack.
•Pop ‘3’ and ‘3’ from the stack, and push ‘27’ (3^3) in the stack.
•Push ‘4’ in the stack.
•Pop ‘4’ and ‘27’ from the stack, multiply them and then push ‘108’ in the stack.
•Push ‘6’ in the stack.
•Pop ‘6’ and ‘108’ from the stack, divide 108 by 6 and then push ‘18’ in the stack.
•Pop ‘18’ and ‘14’ from the stack, subtract 18 from 14 and then push ‘-4’ in the stack.
•Print -4 as the final answer.
4.Write a program to check for balanced parentheses in an expression
#include<iostream>
#include<stack>
using namespace std;
bool isBalanced(string expr)
{
stack<char> s;
char ch;
for (int i=0; i<expr.length(); i++)
{
//for each character in the expression, check conditions
if (expr[i]=='('||expr[i]=='['||expr[i]=='{')
{
//when it is opening bracket, push into stack
s.push(expr[i]);
continue;
}
if (s.empty()) //stack cannot be empty as it is not opening bracket, there must be closing bracket
return false;
switch (expr[i])
{
case ')':
//for closing parenthesis, pop it and check for braces and square brackets
ch = s.top();
s.pop();
if (ch=='{' || ch=='[')
return false;
break;
case '}':
//for closing braces, pop it and check for parenthesis and square brackets
ch = s.top();
s.pop();
if (ch=='(' || ch=='[')
return false;
break;
case ']':
//for closing square bracket, pop it and check for braces and parenthesis
ch = s.top();
s.pop();
if (ch =='(' || ch == '{')
return false;
break;
}
}
return (s.empty()); //when stack is empty, return true
}
main()
{
char expr[200];
cout<<"Enter a string of parenthesis";
cin>>expr;
if (isBalanced(expr))
cout<< "Balanced";
else
cout<< "Not Balanced";
}
4.c.Write a program to check a given String is Palindrome or not.
#include <bits/stdc++.h>
using namespace std;
// Function that returns true
// if string is a palindrome
bool isPalindrome(string s)
{
int length = s.size();
stack<char>st; // Creating a Stack
int i, mid = length / 2; // Finding the mid
for (i = 0; i< mid; i++)
{
st.push(s[i]);
}
// Checking if the length of the string
// is odd, if odd then neglect the
// middle character
if (length % 2 != 0)
{
i++;
}
char ele; // Driver code
// While not the end of the string int main()
while (s[i] != '\0') {
{ char s[200];
ele = st.top(); cout<<"Enter a string ";
st.pop(); cin>>s;
// If the characters differ then the
// given string is not a palindrome if (isPalindrome(s))
{
if (ele != s[i]) cout<< "Yes";
return false; }
i++; else { cout<< "No";
} }
return 0;
return true;
}
}
Applications of Stack:
1. Stacks are used in conversion of infix to postfix expression.
2. Stacks are also used in evaluation of postfix expression.
3. Stacks are used to implement recursive procedures.
4. Stacks are used in compilers.
5. Reverse String

An arithmetic expression can be written in three different but


equivalent notations, i.e., without changing the essence or output
of an expression.

These notations are


1. Infix Notation
2. Prefix (Polish) Notation
3. Postfix (Reverse-Polish) Notation
Conversion of Infix Expressions to Prefix and Postfix
The Tower of Hanoi is a mathematical game or puzzle. It consists
of three rods, and a number of disks of different sizes which can
slide onto any rod. The puzzle starts with the disks in a neat stack in
ascending order of size on one rod, the smallest at the top, thus
making a conical shape.

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

A queue is an ordered collection of data such that the data


is inserted at one end and deleted from another end.

The key difference when compared stacks is that in a


queue the information stored is processed First-in First-out
or FIFO-an element inserted first, will be removed
first.

In other words the information receive from a queue


comes in the same order that it was placed on the queue.
Representing a Queue:
One of the most common way to implement a queue is
using array.

An easy way to do so is to define an array Queue, and two


additional variables front and rear.
The rules for manipulating these variables are simple:

•Each time information is added to the queue, increment rear.

• Each time information is taken from the queue, increment


front.

•Whenever front >rear or front=rear=-1 the queue is empty.

Array implementation of a Queue do have drawbacks:

•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.

The operation of adding new item on the queue occurs only at


one end of the queue called the rear or back.

The operation of removing items of the queue occurs at the


other end called the front.

For insertion and deletion of an element from a queue, the array


elements begin at 0 and the maximum elements of the array is
maxSize.
The variable front will hold the index of the item that is
considered the front of the queue, while the rear variable will
hold the index of the last item in the queue.

Assume that initially the front and rear variables are


initialized to -1. Like stacks, underflow and overflow conditions
are to be checked before operations in a queue.
Applications of Queue:

Queue, as the name suggests is used whenever we need to have


any group of objects in an order in which the first one coming in,
also gets out first while the others wait for there turn, like in the
following scenarios :
1. Serving requests on a single shared resource, like a printer,
CPU task scheduling etc.

2. In real life, Call Center phone systems will use Queues, to


hold people calling them in an order, until a service
representative is free.

3. Handling of interrupts in real-time systems. The interrupts are


handled in the same order as they arrive, First come first
served.
5.A.(i). Write a program that implement Queue (its operations) using Arrays
//code to insert an item into queue;
#include<stdlib.h> template <class T>
#include<iostream> void queue<T> ::insert_q()
using namespace std; {
#define max 5 if(rear>=max-1)
template <class T> cout<<"queue Overflow...\n";
class queue else
{ {
private: if(front>rear)
T q[max],item; front=rear= -1;
int front,rear;
public: else
queue(); {
void insert_q(); if(front== -1)
void delete_q(); front=0;
void display_q(); rear++;
}; cout<<"Enter an item to be inserted:";
template <class T> cin>>item;
queue<T>::queue() q[rear]=item;
{ cout<<"inserted Succesfully..into queue..\n";
front=rear=-1; }
} }
}
template <class T> template <class T>
void queue<T>::delete_q() void queue<T>::display_q()
{ {
if(front==-1||front>rear) if(front==-1||front>rear)
{
front=rear= -1; {
cout<<"queue is Empty\n"; front=rear=-1;
} cout<<"queue is Empty\n";
else }
{ else
item=q[front]; {
front++; for(int i=front;i<=rear;i++)
cout<<item<<" is deleted Successfully
\n"; cout<<"|"<<q[i]<<"|<--";
} }
} }
int main()
{
int choice;
queue<int> q;

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.

A circular queue is a queue in which all locations are treated as


circular such that the first location CQ[0] follows the last
location CQ[max-1].
Normally insertion of elements is done at rear end and delete
the elements from front end.

For example elements 10,20,30 are inserted at rear end.

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

void Queue :: enqueue(int x)


{
S1.push(x);
cout<< "Element Inserted into Queue\n";
}
// dequeue function
// removing the element
int Queue :: dequeue()
{ y = S2.pop();
// moving back the elements to the first stack
int x, y;
while(!S1.isEmpty())
while(!S2.isEmpty())
{ {
// take an element out of first stack x = S2.pop();
x = S1.pop(); S1.push(x);
// insert it into the second stack
S2.push(x);
}
} return y;
}
// main function
int main()
{
Queue q;
q.enqueue(10);
q.enqueue(100);
q.enqueue(1000);
cout<< "Removing element from queue" <<q.dequeue();
return 0;
}
Program-5 (C) Check if a queue can be sorted into another queue using a
stack
#include <bits/stdc++.h>
using namespace std;
bool checkIfPossible(queue<int>&q)
{
stack<int>st;
// Initialize a variable next as 1
int next = 1;
while (!q.empty() || !st.empty())
{
// if front of queue is next, remove it and increment next
if (!q.empty() &&q.front() == next)
{
q.pop();
next++;
}
// if top of stack is next, remove it and increment next
else if (!st.empty() &&st.top() == next)
{
st.pop();
next++;
else
{
// if q is empty return false
if (q.empty())
{
return false;
}
// remove front of queue and push it to top of stack
else
{
int front = q.front();
q.pop();
if (st.empty())
{
st.push(front);
}
else
{
// if front of queue is greater than top of stack, return false
if (front >st.top())
{
return false;
}
else
{
st.push(front);
}
}
}
}
}
return true;
}
int main()
{ // Example 2
// Example 1 queue<int> q2;
queue<int> q1; q2.push(4);
q1.push(8); q2.push(1);
q1.push(7); q2.push(2);
q1.push(5);
q1.push(6);
q2.push(3);
q1.push(4); if (checkIfPossible(q2))
q1.push(3); {
q1.push(2);
q1.push(1); cout<<"true"<<endl;
if (checkIfPossible(q1)) }
{ else
cout<<"true"<<endl; {
}
else
cout<<"false"<<endl;
{ }
cout<<"false"<<endl; return 0;
} }

You might also like