The document describes implementing a queue using an array. It provides algorithms for enQueue() and deQueue() operations. EnQueue() inserts elements at the rear by incrementing rear and checking for full. DeQueue() deletes elements from the front by incrementing front and checking for empty. The queue uses front and rear pointers to manage insertion and deletion of elements based on FIFO principle using an underlying fixed-size array.
Data Structure- Stack operations may involve initializing the stack, using it and then de-initializing it. Apart from these basic stuffs, a stack is used for the following two primary operations −
PUSH, POP, PEEP
Algorithms Lecture 1: Introduction to AlgorithmsMohamed Loey
We will discuss the following: Algorithms, Time Complexity & Space Complexity, Algorithm vs Pseudo code, Some Algorithm Types, Programming Languages, Python, Anaconda.
Data Structure- Stack operations may involve initializing the stack, using it and then de-initializing it. Apart from these basic stuffs, a stack is used for the following two primary operations −
PUSH, POP, PEEP
Algorithms Lecture 1: Introduction to AlgorithmsMohamed Loey
We will discuss the following: Algorithms, Time Complexity & Space Complexity, Algorithm vs Pseudo code, Some Algorithm Types, Programming Languages, Python, Anaconda.
a. Concept and Definition✓
b. Inserting and Deleting nodes ✓
c. Linked implementation of a stack (PUSH/POP) ✓
d. Linked implementation of a queue (Insert/Remove) ✓
e. Circular List
• Stack as a circular list (PUSH/POP) ✓
• Queue as a circular list (Insert/Remove) ✓
f. Doubly Linked List (Insert/Remove) ✓
For more course related material:
https://github.com/ashim888/dataStructureAndAlgorithm/
Personal blog
www.ashimlamichhane.com.np
This presentation deals with pure object oriented concepts and defines basic principles of OOP's like Encapsulation , polymorphism , Inheritance and Abstraction.
Array
Introduction
One-dimensional array
Multidimensional array
Advantage of Array
Write a C program using arrays that produces the multiplication of two matrices.
Python is a widely used high-level programming language for general-purpose programming. Python is a simple, powerful and easy to learn the programming language. It is commonly used for Web and Internet development, Scientific and Numeric computing, Business application and Desktop GUI development etc. The basic data structures in python are lists, dictionaries, tuples, strings and sets
Introduction to control structure in C Programming Language include decision making (if statement, if..else statement, if...else if...else statement, nested if...else statement, switch...case statement), Loop(for loop, while loop, do while loop, nested loop) and using keyword(break, continue and goto)
a. Concept and Definition✓
b. Inserting and Deleting nodes ✓
c. Linked implementation of a stack (PUSH/POP) ✓
d. Linked implementation of a queue (Insert/Remove) ✓
e. Circular List
• Stack as a circular list (PUSH/POP) ✓
• Queue as a circular list (Insert/Remove) ✓
f. Doubly Linked List (Insert/Remove) ✓
For more course related material:
https://github.com/ashim888/dataStructureAndAlgorithm/
Personal blog
www.ashimlamichhane.com.np
This presentation deals with pure object oriented concepts and defines basic principles of OOP's like Encapsulation , polymorphism , Inheritance and Abstraction.
Array
Introduction
One-dimensional array
Multidimensional array
Advantage of Array
Write a C program using arrays that produces the multiplication of two matrices.
Python is a widely used high-level programming language for general-purpose programming. Python is a simple, powerful and easy to learn the programming language. It is commonly used for Web and Internet development, Scientific and Numeric computing, Business application and Desktop GUI development etc. The basic data structures in python are lists, dictionaries, tuples, strings and sets
Introduction to control structure in C Programming Language include decision making (if statement, if..else statement, if...else if...else statement, nested if...else statement, switch...case statement), Loop(for loop, while loop, do while loop, nested loop) and using keyword(break, continue and goto)
Application of Stack For Expression Evaluation by Prakash Zodge DSY 41.pptxPrakash Zodge
In short...The stack organization is very effective in evaluating arithmetic expressions. Expressions are usually represented in what is known as Infix notation, in which each operator is written between two operands (i.e., A + B)....
In computer science, a stack is an abstract data type that serves as a collection of elements, with two main principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed.
The concept of stack is extremely important in computer science and .pdfarihantsherwani
The concept of stack is extremely important in computer science and is used in a wide variety of
problems. This assignment requires you to write a program that can be used to evaluate ordinary
arithmetic expressions that contains any of the five arithmetic operators (+, -, *, /, %).
This exercise requires three distinct steps, namely:-
Verify that the infix arithmetic expression (the original expression), that may contain regular
parentheses, is properly formed as far as parentheses are concerned.
If the parenthesized expression is properly formed, convert the expression from an infix
expression to its equivalent postfix expression, called Reverse Polish Notation (RPN) named
after the Polish Mathematician J. Lukasiewics.
Evaluate the postfix expression, and print the result.
Step 1 - Verify that the expression
Given an arithmetic expression, called an infixed expression, to verify that it is properly formed
as far as parentheses are concerned, do the following:
Create an empty stack to hold left parenthesis ONLY.
Scanned the arithmetic expression from left to right, one character at a time.
While there are more characters in the arithmetic expression
{
If the character is a left parenthesis ‘(‘, push it on to the stack. However if the character is a right
parenthesis, ‘)’, visit the stack and pop the top element from off the stack.
}
If the stack contains any element at the end of reading the arithmetic expression, then the
expression was not properly formed.
Step 2 - Convert infixed expression to postfix
Given that an arithmetic expression is properly form with respect to parentheses, do the
following:
Create an empty stack to hold any arithmetic operators and left parenthesis, ONLY.
A string to contain the postfix expression – the output from this conversion.
Scan the arithmetic expression from left to right.
While the are more symbols in the arithmetic expression,
{
After a symbol is scanned, there are four (4) basic rules to observed and apply accordingly:
If the symbol is an operand (a number), write it to the output string.
If the symbol is an operator and if the stack is empty, push the symbol on the stack.
Otherwise, if the symbol is either ‘(‘ or ‘)’, check for the following conditions:
If the symbol is ‘(‘, push on to the stack,
Otherwise
If the symbol is ‘)’
{
Pop everything from the operator stack down to the first ‘(‘. Write each item
popped from the stack to the output string. Do not write the item ‘)’. Discard it.
}
If the symbol scanned is an arithmetic operator, check for the following and apply accordingly:
If the operator on the top of the stack has higher or equal precedence, that operator is popped
from off the stack, and is written to the to the output string. This process is continues until one of
two things happen:
Either the first ‘(‘ is encountered. When this occurs, the ‘(‘ is removed from the stack and is
discarded, and the recently scanned symbol is placed on the stack
OR
The operator on the stack has lower preced.
The Roman Empire A Historical Colossus.pdfkaushalkr1407
The Roman Empire, a vast and enduring power, stands as one of history's most remarkable civilizations, leaving an indelible imprint on the world. It emerged from the Roman Republic, transitioning into an imperial powerhouse under the leadership of Augustus Caesar in 27 BCE. This transformation marked the beginning of an era defined by unprecedented territorial expansion, architectural marvels, and profound cultural influence.
The empire's roots lie in the city of Rome, founded, according to legend, by Romulus in 753 BCE. Over centuries, Rome evolved from a small settlement to a formidable republic, characterized by a complex political system with elected officials and checks on power. However, internal strife, class conflicts, and military ambitions paved the way for the end of the Republic. Julius Caesar’s dictatorship and subsequent assassination in 44 BCE created a power vacuum, leading to a civil war. Octavian, later Augustus, emerged victorious, heralding the Roman Empire’s birth.
Under Augustus, the empire experienced the Pax Romana, a 200-year period of relative peace and stability. Augustus reformed the military, established efficient administrative systems, and initiated grand construction projects. The empire's borders expanded, encompassing territories from Britain to Egypt and from Spain to the Euphrates. Roman legions, renowned for their discipline and engineering prowess, secured and maintained these vast territories, building roads, fortifications, and cities that facilitated control and integration.
The Roman Empire’s society was hierarchical, with a rigid class system. At the top were the patricians, wealthy elites who held significant political power. Below them were the plebeians, free citizens with limited political influence, and the vast numbers of slaves who formed the backbone of the economy. The family unit was central, governed by the paterfamilias, the male head who held absolute authority.
Culturally, the Romans were eclectic, absorbing and adapting elements from the civilizations they encountered, particularly the Greeks. Roman art, literature, and philosophy reflected this synthesis, creating a rich cultural tapestry. Latin, the Roman language, became the lingua franca of the Western world, influencing numerous modern languages.
Roman architecture and engineering achievements were monumental. They perfected the arch, vault, and dome, constructing enduring structures like the Colosseum, Pantheon, and aqueducts. These engineering marvels not only showcased Roman ingenuity but also served practical purposes, from public entertainment to water supply.
Read| The latest issue of The Challenger is here! We are thrilled to announce that our school paper has qualified for the NATIONAL SCHOOLS PRESS CONFERENCE (NSPC) 2024. Thank you for your unwavering support and trust. Dive into the stories that made us stand out!
Operation “Blue Star” is the only event in the history of Independent India where the state went into war with its own people. Even after about 40 years it is not clear if it was culmination of states anger over people of the region, a political game of power or start of dictatorial chapter in the democratic setup.
The people of Punjab felt alienated from main stream due to denial of their just demands during a long democratic struggle since independence. As it happen all over the word, it led to militant struggle with great loss of lives of military, police and civilian personnel. Killing of Indira Gandhi and massacre of innocent Sikhs in Delhi and other India cities was also associated with this movement.
Welcome to TechSoup New Member Orientation and Q&A (May 2024).pdfTechSoup
In this webinar you will learn how your organization can access TechSoup's wide variety of product discount and donation programs. From hardware to software, we'll give you a tour of the tools available to help your nonprofit with productivity, collaboration, financial management, donor tracking, security, and more.
Embracing GenAI - A Strategic ImperativePeter Windle
Artificial Intelligence (AI) technologies such as Generative AI, Image Generators and Large Language Models have had a dramatic impact on teaching, learning and assessment over the past 18 months. The most immediate threat AI posed was to Academic Integrity with Higher Education Institutes (HEIs) focusing their efforts on combating the use of GenAI in assessment. Guidelines were developed for staff and students, policies put in place too. Innovative educators have forged paths in the use of Generative AI for teaching, learning and assessments leading to pockets of transformation springing up across HEIs, often with little or no top-down guidance, support or direction.
This Gasta posits a strategic approach to integrating AI into HEIs to prepare staff, students and the curriculum for an evolving world and workplace. We will highlight the advantages of working with these technologies beyond the realm of teaching, learning and assessment by considering prompt engineering skills, industry impact, curriculum changes, and the need for staff upskilling. In contrast, not engaging strategically with Generative AI poses risks, including falling behind peers, missed opportunities and failing to ensure our graduates remain employable. The rapid evolution of AI technologies necessitates a proactive and strategic approach if we are to remain relevant.
Biological screening of herbal drugs: Introduction and Need for
Phyto-Pharmacological Screening, New Strategies for evaluating
Natural Products, In vitro evaluation techniques for Antioxidants, Antimicrobial and Anticancer drugs. In vivo evaluation techniques
for Anti-inflammatory, Antiulcer, Anticancer, Wound healing, Antidiabetic, Hepatoprotective, Cardio protective, Diuretics and
Antifertility, Toxicity studies as per OECD guidelines
2024.06.01 Introducing a competency framework for languag learning materials ...Sandy Millin
http://sandymillin.wordpress.com/iateflwebinar2024
Published classroom materials form the basis of syllabuses, drive teacher professional development, and have a potentially huge influence on learners, teachers and education systems. All teachers also create their own materials, whether a few sentences on a blackboard, a highly-structured fully-realised online course, or anything in between. Despite this, the knowledge and skills needed to create effective language learning materials are rarely part of teacher training, and are mostly learnt by trial and error.
Knowledge and skills frameworks, generally called competency frameworks, for ELT teachers, trainers and managers have existed for a few years now. However, until I created one for my MA dissertation, there wasn’t one drawing together what we need to know and do to be able to effectively produce language learning materials.
This webinar will introduce you to my framework, highlighting the key competencies I identified from my research. It will also show how anybody involved in language teaching (any language, not just English!), teacher training, managing schools or developing language learning materials can benefit from using the framework.
June 3, 2024 Anti-Semitism Letter Sent to MIT President Kornbluth and MIT Cor...Levi Shapiro
Letter from the Congress of the United States regarding Anti-Semitism sent June 3rd to MIT President Sally Kornbluth, MIT Corp Chair, Mark Gorenberg
Dear Dr. Kornbluth and Mr. Gorenberg,
The US House of Representatives is deeply concerned by ongoing and pervasive acts of antisemitic
harassment and intimidation at the Massachusetts Institute of Technology (MIT). Failing to act decisively to ensure a safe learning environment for all students would be a grave dereliction of your responsibilities as President of MIT and Chair of the MIT Corporation.
This Congress will not stand idly by and allow an environment hostile to Jewish students to persist. The House believes that your institution is in violation of Title VI of the Civil Rights Act, and the inability or
unwillingness to rectify this violation through action requires accountability.
Postsecondary education is a unique opportunity for students to learn and have their ideas and beliefs challenged. However, universities receiving hundreds of millions of federal funds annually have denied
students that opportunity and have been hijacked to become venues for the promotion of terrorism, antisemitic harassment and intimidation, unlawful encampments, and in some cases, assaults and riots.
The House of Representatives will not countenance the use of federal funds to indoctrinate students into hateful, antisemitic, anti-American supporters of terrorism. Investigations into campus antisemitism by the Committee on Education and the Workforce and the Committee on Ways and Means have been expanded into a Congress-wide probe across all relevant jurisdictions to address this national crisis. The undersigned Committees will conduct oversight into the use of federal funds at MIT and its learning environment under authorities granted to each Committee.
• The Committee on Education and the Workforce has been investigating your institution since December 7, 2023. The Committee has broad jurisdiction over postsecondary education, including its compliance with Title VI of the Civil Rights Act, campus safety concerns over disruptions to the learning environment, and the awarding of federal student aid under the Higher Education Act.
• The Committee on Oversight and Accountability is investigating the sources of funding and other support flowing to groups espousing pro-Hamas propaganda and engaged in antisemitic harassment and intimidation of students. The Committee on Oversight and Accountability is the principal oversight committee of the US House of Representatives and has broad authority to investigate “any matter” at “any time” under House Rule X.
• The Committee on Ways and Means has been investigating several universities since November 15, 2023, when the Committee held a hearing entitled From Ivory Towers to Dark Corners: Investigating the Nexus Between Antisemitism, Tax-Exempt Universities, and Terror Financing. The Committee followed the hearing with letters to those institutions on January 10, 202
Introduction to AI for Nonprofits with Tapp NetworkTechSoup
Dive into the world of AI! Experts Jon Hill and Tareq Monaur will guide you through AI's role in enhancing nonprofit websites and basic marketing strategies, making it easy to understand and apply.
Instructions for Submissions thorugh G- Classroom.pptxJheel Barad
This presentation provides a briefing on how to upload submissions and documents in Google Classroom. It was prepared as part of an orientation for new Sainik School in-service teacher trainees. As a training officer, my goal is to ensure that you are comfortable and proficient with this essential tool for managing assignments and fostering student engagement.
Instructions for Submissions thorugh G- Classroom.pptx
Data structure lab manual
1. PRACTICAL NO. 1
Problem Definition: Implementation of stack using array
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
A Stack is one of the most common Data Structure. We can implement stack using an Array or
Linked list. Stack has only one end referred as TOP. So the element can only be inserted and
removed from TOP only. Hence Stack is also known as LIFO (Last In First Out). The various
functions of Stack are PUSH(), POP() and PEEK().
● PUSH(): For inserting element in the Stack.
● POP(): For deleting element from the Stack.
● PEEK(): To return the top element of Stack
Algorithm:
Algorithm for PUSH() operation in Stack using Array:
Step 1: Start
Step 2: Declare Stack[MAX]; //Maximum size of Stack
Step 3: Check if the stack is full or not by comparing top with (MAX-1)
If the stack is full, Then print "Stack Overflow"
i.e, stack is full and cannot be pushed with another element
Step 4: Else, the stack is not full
Increment top by 1 and Set, a[top] = x
which pushes the element x into the address pointed by top.
// The element x is stored in a[top]
Step 5: Stop
2. Algorithm for POP() operation in Stack using Array:
Step 1: Start
Step 2: Declare Stack[MAX]
Step 3: Push the elements into the stack
Step 4: Check if the stack is empty or not by comparing top with base of array
i.e 0 If top is less than 0, then stack is empty,
print "Stack Underflow"
Step 5: Else, If top is greater than zero the stack is not empty,
then store the value pointed by top in a variable x=a[top] and decrement top by 1.
The popped element is x.
Algorithm for PEEK() operation in Stack using Arrays:
Step 1: Start
Step 2: Declare Stack[MAX]
Step 3: Push the elements into the stack
Step 4: Print the value stored in the stack pointed by top.
Step 6: Stop
Program:
#include<stdio.h>
#define MAX 5
struct stack
{
int data[MAX];
int top;
};
void initialize(struct stack *s)
{
s->top=-1;
}
int isEmpty(struct stack *s)
{
if(s->top==-1) // return s->top==-1?1:0;
return 1;
else
return 0;
}
4. {
int d;
d=s->data[s->top];
//s->top--; //d=s->data[s->top--];
printf("nData at peek is %d",d);
//return s->data[s->top--];
}
}
void display(struct stack *s)
{
int i;
if(s->top==-1)
printf("ntStack is Empty->");
else
{
printf("nStack Contents ->->n");
for(i=s->top;i>=0;i--)
{
printf("%dn",s->data[i]);
}
}
}
int main()
{
int ch,d;
struct stack s;
//s->top=-1;
initialize(&s);
while(1)
{
printf("ntttMENUn1. Push.n2. Pop.n3. Peek.");
printf("n4. Display.n5. Exit.");
printf("ntEnter your choice :: ");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("nEnter Data to be Pushed : ");
5. scanf("%d",&d);
if(push(&s,d))
printf("nPushed successfully");
else
printf("nCannot Push..");
break;
case 2:
pop(&s);
break;
case 3:
peek(&s);
break;
case 4:
display(&s);
break;
case 5:
exit(0);
default:
printf("ntPlease enter correct choice->->->->");
}
}
}
Output Screenshot:
Conclusion:
An array can be used to implement a stack. The size of the stack is simply the size of the array,
which is a very efficient implementation of a stack since adding items to or removing items from
the TOP requires amortized O(1) time.
7. PRACTICAL NO. 2
Problem Definition: Write a program that uses stack operations to convert a given infix expression
into its postfix Equivalent and implement the stack using an array.
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
To convert Infix expression to postfix expression, we will use the stack data structure. By scanning
the infix expression from left to right, if we get any operand, simply add it to the postfix form, and
for the operator and parenthesis, add them in the stack maintaining the precedence of them.
Infix Expression: Infix Expression contains operator in-between every pair of operands,
Expression of the form a op b.
Postfix expression: Postfix Expression contains operator followed for every pair of operands,
Expression of the form a b op.
Why postfix representation of the expression?
● Infix expressions are readable and solvable by humans because of easily distinguishable
order of operators, but compiler doesn't have integrated order of operators.
● Hence to solve the Infix Expression compiler will scan the expression multiple times to
solve the sub-expressions in expressions orderly which is very in-efficient.
● To avoid this traversing, Infix expressions are converted to Postfix expression before
evaluation.
Algorithm
● Step 1 : Scan the Infix Expression from left to right.
● Step 2 : If the scanned character is an operand, append it with final Infix to Postfix string.
● Step 3 : Else,
○ Step 3.1 : If the precedence order of the scanned(incoming) operator is greater than
the precedence order of the operator in the stack (or the stack is empty or the stack
contains a ‘(‘ or ‘[‘ or ‘{‘), push it on stack.
○ Step 3.2 : Else, Pop all the operators from the stack which are greater than or equal
to in precedence than that of the scanned operator. After doing that Push the
scanned operator to the stack. (If you encounter parenthesis while popping then
stop there and push the scanned operator in the stack.)
● Step 4 : If the scanned character is an ‘(‘ or ‘[‘ or ‘{‘, push it to the stack.
8. ● Step 5 : If the scanned character is an ‘)’or ‘]’ or ‘}’, pop the stack and and output it until
a ‘(‘ or ‘[‘ or ‘{‘ respectively is encountered, and discard both the parenthesis.
● Step 6 : Repeat steps 2-6 until infix expression is scanned.
● Step 7 : Print the output
● Step 8 : Pop and output from the stack until it is not empty.
Example:
Infix Expression: A+ (B*C-(D/E^F)*G)*H, where ^ is an exponential operator.
Resultant Postfix Expression: ABC*DEF^/G*-H*+
12. Conclusion:
An infix expression is difficult for the machine to know and keep track of the precedence of
operators. On the other hand, a postfix expression itself determines the precedence of operators (as
the placement of operators in a postfix expression depends upon its precedence).Therefore, for the
machine it is easier to carry out a postfix expression than an infix expression.
References:
https://en.wikipedia.org/wiki/Reverse_Polish_notation
Post Lab Assignment:
Q1. Click on the following link and solve the quiz and paste screenshot of score
https://www.geeksforgeeks.org/data-structure-gq/stack-gq/
13. PRACTICAL NO. 3
Problem Definition: To evaluate a given postfix expression using a stack.
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
The Postfix notation is used to represent algebraic expressions. The expressions written in postfix
form are evaluated faster compared to infix notation as parenthesis are not required in postfix.
Algorithm:
1) Create a stack to store operands (or values).
2) Scan the given expression and do the following for every scanned element.
a) If the element is a number, push it into the stack
b) If the element is an operator, pop operands for the operator from the stack. Evaluate the
operator and push the result back to the stack
3) When the expression is ended, the number in the stack is the final answer
Example:
Let the given expression be “2 3 1 * + 9 -“. We scan all elements one by one.
1) Scan ‘2’, it’s a number, so push it to stack. Stack contains ‘2’
2) Scan ‘3’, again a number, push it to stack, stack now contains ‘2 3’ (from bottom to top)
3) Scan ‘1’, again a number, push it to stack, stack now contains ‘2 3 1’
4) Scan ‘*’, it’s an operator, pop two operands from stack, apply the * operator on operands, we
get 3*1 which results in 3. We push the result ‘3’ to stack. The stack now becomes ‘2 3’.
5) Scan ‘+’, it’s an operator, pop two operands from stack, apply the + operator on operands, we
get 3 + 2 which results in 5. We push the result ‘5’ to stack. The stack now becomes ‘5’.
6) Scan ‘9’, it’s a number, we push it to the stack. The stack now becomes ‘5 9’.
7) Scan ‘-‘, it’s an operator, pop two operands from stack, apply the – operator on operands, we
get 5 – 9 which results in -4. We push the result ‘-4’ to the stack. The stack now becomes ‘-4’.
8) There are no more elements to scan, we return the top element from the stack (which is the only
element left in a stack).
14. Example:
Let the given expression be “456*+“. We scan all elements one by one.
Program:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAX 50
struct stack
{
int data[MAX];
int top;
};
int empty(struct stack *s)
{
return (s->top==-1)?1:0;
}
17. Conclusion:
As Postfix expression is without parentheses and can be evaluated as two operands and an
operator at a time, this becomes easier for the compiler and the computer to handle.
References:
https://en.wikipedia.org/wiki/Postfix
Post Lab Assignment:
Q1. Click on the following link and solve the problem and paste screenshot of score
https://practice.geeksforgeeks.org/problems/evaluation-of-postfix-expression1735/1
18. PRACTICAL NO. 4
Problem Definition: To implement a queue using an array.
Compiler / Tool : Turbo/Borland C complier
https://www.onlinegdb.com/
Theory:
A queue data structure can be implemented using a one dimensional array. The queue implemented
using an array stores only a fixed number of data values. The implementation of queue data
structure using arrays is very simple. Just define a one dimensional array of specific size and insert
or delete the values into that array by using FIFO (First In First Out) principle with the help of
variables 'front' and 'rear'. Initially both 'front' and 'rear' are set to -1. Whenever, we want to
insert a new value into the queue, increment the 'rear' value by one and then insert at that position.
Whenever we want to delete a value from the queue, then delete the element which is at 'front'
position and increment 'front' value by one.
Algorithm:
enQueue(value) - Inserting value into the queue
In a queue data structure, enQueue() is a function used to insert a new element into the queue. In
a queue, the new element is always inserted at rear position. The enQueue() function takes one
integer value as a parameter and inserts that value into the queue. We can use the following steps
to insert an element into the queue...
● Step 1 - Check whether queue is FULL. (rear == SIZE-1)
● Step 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not possible!!!" and
terminate the function.
● Step 3 - If it is NOT FULL, then increment rear value by one (rear++) and set
queue[rear] = value.
deQueue() - Deleting a value from the Queue
In a queue data structure, deQueue() is a function used to delete an element from the queue. In a
queue, the element is always deleted from front position. The deQueue() function does not take
any value as parameter. We can use the following steps to delete an element from the queue...
● Step 1 - Check whether queue is EMPTY. (front == rear)
● Step 2 - If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not possible!!!"
and terminate the function.
19. ● Step 3 - If it is NOT EMPTY, then increment the front value by one (front ++). Then
display queue[front] as deleted element. Then check whether both front and rear are
equal (front == rear), if it TRUE, then set both front and rear to '-1' (front = rear = -1).
display() - Displays the elements of a Queue
We can use the following steps to display the elements of a queue...
● Step 1 - Check whether queue is EMPTY. (front == rear)
● Step 2 - If it is EMPTY, then display "Queue is EMPTY!!!" and terminate the function.
● Step 3 - If it is NOT EMPTY, then define an integer variable 'i' and set 'i = front+1'.
● Step 4 - Display 'queue[i]' value and increment 'i' value by one (i++). Repeat the same until
'i' value reaches to rear (i <= rear)
Program:
#include<stdio.h>
#define MAX 5
struct Queue
{
int data[MAX];
int front,rear;
};
void initialize(struct Queue *q)
{
q->front=q->rear=-1;
}
int isFull(struct Queue *q)
{
return (q->rear==MAX-1)?1:0;
}
int isEmpty(struct Queue *q)
{
return (q->rear==-1)?1:0;
}
int insert(struct Queue *q,int d)
21. int i;
for(i=q->front;i<=q->rear;i++)
if(q->data[i]==k)
return i;
return -1;
}
int main()
{
int ch,d;
struct Queue q;
initialize(&q);
while(1)
{
printf("ntttMENUn1. Insert.n2. Delete.n3. Search.");
printf("n4. Display.n5. Exit.");
printf("ntEnter your choice :: ");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("nEnter Data to be Inserted : ");
scanf("%d",&d);
d=insert(&q,d);
if(d==0)
printf("Queue is full...");
else
printf("Insertion done successfully...");
break;
case 2:
if(isEmpty(&q))
printf("nQueue is empty...");
else
printf("nDeleted element is %d",delete(&q));
break;
case 3:
printf("nEnter Data to be Searched : ");
scanf("%d",&d);
d=search(&q,d);
22. if(d==-1)
printf("nKey is not found..");
else
printf("nKey is found at location %d..",d);
break;
case 4:
display(&q);
break;
case 5:
exit(0);
default:
printf("ntPlease enter correct choice->->->->");
}
}
}
Output Screenshot:
Conclusion:
We can easily represent the queue by using linear arrays. There are two variables i.e. front and rear
that are implemented in the case of every queue. Front and rear variables point to the position from
where insertions and deletions are performed in a queue. Initially, the value of front and queue is
-1 which represents an empty queue.
References:
https://en.wikipedia.org/wiki/Queue_(abstract_data_type)
24. PRACTICAL NO. 5
Problem Definition: To implement a circular queue using an array.
Compiler / Tool : Turbo/Borland C complier
https://www.onlinegdb.com/
Theory:
Circular Queue is a linear data structure in which the operations are performed based on FIFO
(First In First Out) principle and the last position is connected back to the first position to make a
circle. It is also called ‘Ring Buffer’.
The circular queue work as follows:
● two pointers FRONT and REAR
● FRONT track the first element of the queue
● REAR track the last elements of the queue
● initially, set value of FRONT and REAR to -1
1. Enqueue Operation
● check if the queue is full
● for the first element, set value of FRONT to 0
● circularly increase the REAR index by 1 (i.e. if the rear reaches the end, next it would be
at the start of the queue)
● add the new element in the position pointed to by REAR
2. Dequeue Operation
25. ● check if the queue is empty
● return the value pointed by FRONT
● circularly increase the FRONT index by 1
● for the last element, reset the values of FRONT and REAR to -1
However, the check for full queue has a new additional case:
● Case 1: FRONT = 0 && REAR == SIZE - 1
● Case 2: FRONT = REAR + 1
The second case happens when REAR starts from 0 due to circular increment and when its value
is just 1 less than FRONT, the queue is full.
Algorithm:
To implement a circular queue data structure using an array, we first perform the following steps
before we implement actual operations.
● Step 1 - Include all the header files which are used in the program and define a constant
'SIZE' with specific value.
● Step 2 - Declare all user defined functions used in circular queue implementation.
● Step 3 - Create a one dimensional array with above defined SIZE (int cQueue[SIZE])
● Step 4 - Define two integer variables 'front' and 'rear' and initialize both with '-1'. (int
front = -1, rear = -1)
● Step 5 - Implement main method by displaying menu of operations list and make suitable
function calls to perform operations selected by the user on a circular queue.
enQueue(value) - Inserting value into the Circular Queue
In a circular queue, enQueue() is a function which is used to insert an element into the circular
queue. In a circular queue, the new element is always inserted at rear position. The enQueue()
function takes one integer value as parameter and inserts that value into the circular queue. We can
use the following steps to insert an element into the circular queue...
● Step 1 - Check whether the queue is FULL. ((rear == SIZE-1 && front == 0) || (front
== rear+1))
● Step 2 - If it is FULL, then display "Queue is FULL!!! Insertion is not possible!!!" and
terminate the function.
● Step 3 - If it is NOT FULL, then check rear == SIZE - 1 && front != 0 if it is TRUE,
then set rear = -1.
● Step 4 - Increment rear value by one (rear++), set queue[rear] = value and check 'front
== -1' if it is TRUE, then set front = 0.
26. deQueue() - Deleting a value from the Circular Queue
In a circular queue, deQueue() is a function used to delete an element from the circular queue. In
a circular queue, the element is always deleted from front position. The deQueue() function doesn't
take any value as a parameter. We can use the following steps to delete an element from the circular
queue...
● Step 1 - Check whether the queue is EMPTY. (front == -1 && rear == -1)
● Step 2 - If it is EMPTY, then display "Queue is EMPTY!!! Deletion is not possible!!!"
and terminate the function.
● Step 3 - If it is NOT EMPTY, then display queue[front] as a deleted element and
increment the front value by one (front ++). Then check whether front == SIZE, if it is
TRUE, then set front = 0. Then check whether both front - 1 and rear are equal (front -
1 == rear), if it is TRUE, then set both front and rear to '-1' (front = rear = -1).
display() - Displays the elements of a Circular Queue
We can use the following steps to display the elements of a circular queue...
● Step 1 - Check whether the queue is EMPTY. (front == -1)
● Step 2 - If it is EMPTY, then display "Queue is EMPTY!!!" and terminate the function.
● Step 3 - If it is NOT EMPTY, then define an integer variable 'i' and set 'i = front'.
● Step 4 - Check whether 'front <= rear', if it is TRUE, then display 'queue[i]' value and
increment 'i' value by one (i++). Repeat the same until 'i <= rear' becomes FALSE.
● Step 5 - If 'front <= rear' is FALSE, then display 'queue[i]' value and increment 'i' value
by one (i++). Repeat the same until'i <= SIZE - 1' becomes FALSE.
● Step 6 - Set i to 0.
● Step 7 - Again display 'cQueue[i]' value and increment i value by one (i++). Repeat the
same until 'i <= rear' becomes FALSE.
Program:
#include<stdio.h>
#include<stdlib.h>
#define MAX 5
struct queue //Declare Queue
{
int data[MAX];
int front, rear;
};
27. void //Initialize Queue
initialize (struct queue *q)
{
q->rear = q->front = -1;
}
int
isEmpty (struct queue *q) //Check if queue is empty
{
return (q->rear == -1);
}
int
isFull (struct queue *q) //Check if queue is full
{
return (q->front == ((q->rear + 1) % MAX)) ? 1 : 0;
}
int
Insert (struct queue *q, int d)
{
if (isFull (q))
{
printf ("ttnQUEUE IS FULLn");
return 0;
}
else
{
q->rear = (q->rear + 1) % MAX;
q->data[q->rear] = d;
printf ("n DATA INSERTION SUCCESFULLY!n");
if (q->front == -1)
q->front = 0;
return 1;
}
}
int
Delete (struct queue *q)
{
28. if (isEmpty (q))
{
printf ("nt QUEUE IS EMPTYn");
return 0;
}
else
{
int a;
a = q->data[q->front];
if (q->front == q->rear)
q->front = q->rear = -1;
else
q->front = (q->front + 1) % MAX;
printf ("nt ELEMENT DELETED FROM QUEUE IS %dn", a);
return 0;
}
}
int
Search (struct queue *q, int s)
{
int i = 0;
for (i = q->front; i != q->rear + 1; i = (i + 1) % MAX)
if (q->data[i] == s)
return i;
return -1;
}
void
Display (struct queue *q)
{
int i;
if (q->rear == -1)
printf ("nt QUEUE IS EMPTYn");
else
{
printf ("n QUEUE CONTENTS ARE :n");
for (i = q->front; i != q->rear; i = (i + 1) % MAX)
{
29. printf ("%dn", q->data[i]);
}
printf ("%dn", q->data[i]);
}
}
int
main ()
{
int ch, d;
struct queue q;
initialize (&q);
while (1)
{
printf
("ntttMENUn1.INSERTn2.DELETEn3.SEARCHn4.DISPLAYn0.EXITn");
printf ("nENTER YOUR CHOICE: ");
scanf ("%d", &ch);
switch (ch)
{
case 1:
printf ("nENTER DATA TO BE INSERTED: ");
scanf ("%d", &d);
Insert (&q, d);
break;
case 2:
Delete (&q);
break;
case 3:
printf ("n ENTER THE ELEMENT FOR SEARCH: ");
scanf ("%d", &d);
d = Search (&q, d);
if (d == -1)
printf ("nTHE ELEMENT IS NOT PRESENT INSIDE THE QUEUEn");
else
printf ("THE ELEMENT IS FOUND IS AT %dn", d + 1);
break;
30. case 4:
Display (&q);
break;
case 0:
exit (0);
break;
default:
printf ("ENTER A VALID CHOICEn");
}
}
}
Output Screenshot:
Conclusion:
A circular queue is a very important data structure because it can store data in a very practical way.
The circular queue is a linear data structure. It follows the FIFO principle. In a circular queue, the
last node is connected back to the first node to make a circle. Circular array list follows the First
In First Out principle. Elements are added at the rear end and the elements are deleted at the front
end of the queue.
References:
https://en.wikipedia.org/wiki/Circular_buffer
31. Post Lab Assignment:
Click on the following link and solve the problem and paste screenshot of score
https://quizizz.com/admin/quiz/5f3f60aef7f2c3001c6feea6/circular-queue
32. PRACTICAL NO. 6
Problem Definition: Write a program that uses functions to perform the following:
a) Create a singly linked list of integers.
b) Insert a given integer into the linked list
c) Delete a given integer from the singly linked list.
d) Display the contents of the above list after insertion and deletion
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
When we want to work with an unknown number of data values, we use a linked list data structure
to organize that data. The linked list is a linear data structure that contains a sequence of elements
such that each element links to its next element in the sequence. Each element in a linked list is
called "Node".
The formal definition of a single linked list is “Single linked list is a sequence of elements in which
every element has a link to its next element in the sequence”.
In any single linked list, the individual element is called "Node". Every "Node" contains two fields,
a data field, and the next field. The data field is used to store the actual value of the node and the
next field is used to store the address of the next node in the sequence. The graphical representation
of a node in a single linked list is as follows
In a single linked list, the address of the first node is always stored in a reference node known as
"front" (Some times it is also known as "head"). Always next part (reference part) of the last node
must be NULL.
Algorithm:
33. Operations on Single Linked List
The following operations are performed on a Single Linked List
● Insertion
● Deletion
● Display
Before we implement actual operations, first we need to set up an empty list. First, perform the
following steps before implementing actual operations.
● Step 1 - Include all the header files which are used in the program.
● Step 2 - Declare all the user defined functions.
● Step 3 - Define a Node structure with two members data and next
● Step 4 - Define a Node pointer 'head' and set it to NULL.
● Step 5 - Implement the main method by displaying operations menu and make suitable
function calls in the main method to perform user selected operation.
Insertion
In a single linked list, the insertion operation can be performed in three ways. They are as follows...
1. Inserting At Beginning of the list
2. Inserting At End of the list
3. Inserting At Specific location in the list
Inserting At Beginning of the list
We can use the following steps to insert a new node at beginning of the single linked list...
● Step 1 - Create a newNode with given value.
● Step 2 - Check whether list is Empty (head == NULL)
● Step 3 - If it is Empty then, set newNode→next = NULL and head = newNode.
● Step 4 - If it is Not Empty then, set newNode→next = head and head = newNode.
Inserting At End of the list
We can use the following steps to insert a new node at end of the single linked list...
● Step 1 - Create a newNode with given value and newNode → next as NULL.
● Step 2 - Check whether list is Empty (head == NULL).
34. ● Step 3 - If it is Empty then, set head = newNode.
● Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
● Step 5 - Keep moving the temp to its next node until it reaches to the last node in the list
(until temp → next is equal to NULL).
● Step 6 - Set temp → next = newNode.
Inserting At Specific location in the list (After a Node)
We can use the following steps to insert a new node after a node in the single linked list...
● Step 1 - Create a newNode with a given value.
● Step 2 - Check whether list is Empty (head == NULL)
● Step 3 - If it is Empty then, set newNode → next = NULL and head = newNode.
● Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
● Step 5 - Keep moving the temp to its next node until it reaches the node after which we
want to insert the newNode (until temp1 → data is equal to location, here location is the
node value after which we want to insert the newNode).
● Step 6 - Every time check whether temp has reached the last node or not. If it is reached
to the last node then display 'Given node is not found in the list!!! Insertion is not
possible!!!' and terminate the function. Otherwise move the temp to the next node.
● Step 7 - Finally, Set 'newNode → next = temp → next' and 'temp → next = newNode'
Deletion
In a single linked list, the deletion operation can be performed in three ways. They are as follows...
1. Deleting from Beginning of the list
2. Deleting from End of the list
3. Deleting a Specific Node
Deleting from Beginning of the list
We can use the following steps to delete a node from the beginning of the single linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with head.
● Step 4 - Check whether list is having only one node (temp → next == NULL)
35. ● Step 5 - If it is TRUE then set head = NULL and delete temp (Setting Empty list
conditions)
● Step 6 - If it is FALSE then set head = temp → next, and delete temp.
Deleting from End of the list
We can use the following steps to delete a node from the end of the single linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.
● Step 4 - Check whether list has only one Node (temp1 → next == NULL)
● Step 5 - If it is TRUE. Then, set head = NULL and delete temp1. And terminate the
function. (Setting Empty list condition)
● Step 6 - If it is FALSE. Then, set 'temp2 = temp1 ' and move temp1 to its next node.
Repeat the same until it reaches the last node in the list. (until temp1 → next == NULL)
● Step 7 - Finally, Set temp2 → next = NULL and delete temp1.
Deleting a Specific Node from the list
We can use the following steps to delete a specific node from the single linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.
● Step 4 - Keep moving the temp1 until it reaches the exact node to be deleted or to the last
node. And every time set 'temp2 = temp1' before moving the 'temp1' to its next node.
● Step 5 - If it is reached to the last node then display 'Given node not found in the list!
Deletion is not possible!!!'. And terminate the function.
● Step 6 - If it is reached to the exact node which we want to delete, then check whether list
is having only one node or not
● Step 7 - If the list has only one node and that is the node to be deleted, then set head =
NULL and delete temp1 (free(temp1)).
● Step 8 - If the list contains multiple nodes, then check whether temp1 is the first node in
the list (temp1 == head).
36. ● Step 9 - If temp1 is the first node then move the head to the next node (head = head →
next) and delete temp1.
● Step 10 - If temp1 is not the first node then check whether it is the last node in the list
(temp1 → next == NULL).
● Step 11 - If temp1 is the last node then set temp2 → next = NULL and delete temp1
(free(temp1)).
● Step 12 - If temp1 is not the first node and not the last node then set temp2 → next =
temp1 → next and delete temp1 (free(temp1)).
Displaying a Single Linked List
We can use the following steps to display the elements of a single linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!!' and terminate the function.
● Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with head.
● Step 4 - Keep displaying temp → data with an arrow (--->) until temp reaches to the last
node
● Step 5 - Finally display temp → data with an arrow pointing to NULL (temp → data ---
> NULL).
Program:
#include<stdio.h>
#include<stdlib.h>
struct SLL /* Global structure to create a node*/
{
int data;
struct SLL *next;
};
struct SLL *insertAtEnd(struct SLL *h,int d)
{
struct SLL *p,*tmp;
p=(struct SLL *)malloc(sizeof(struct SLL)); //creating a new node
if(p==NULL)
{
printf("nNot enough memory to allocate.");
return h;
}
p->data=d; //putting data into new node
p->next=NULL; //making new node point to null
37. if(h==NULL) // LL is empty
h=p;
else
{ //LL is not empty
tmp=h;
while(tmp->next!=NULL) //to traverse to the last node
tmp=tmp->next;
tmp->next=p;
}
return h;
}
struct SLL *insertAtStart(struct SLL *h,int d)
{
struct SLL *p,*tmp;
p=(struct SLL *)malloc(sizeof(struct SLL)); //creating a new node
p->data=d; //putting data into new node
p->next=h; //making new node point to null
h=p;
return h;
}
struct SLL *insertAfter(struct SLL *h,int key,int d)
{
struct SLL *p,*tmp;
p=(struct SLL *)malloc(sizeof(struct SLL)); //creating a new node
p->data=d; //putting data into new node
p->next=NULL; //making new node point to null
if(h==NULL)
{ // LL is empty
h=p;
}
else
{ //LL is not empty
tmp=h;
while(tmp!=NULL && tmp->data!=key ) //to traverse to the last node
tmp=tmp->next;
if(tmp!=NULL)
{
39. tmp=h;
if(h!=NULL)
{
h=h->next;
free(tmp);
}
else
printf("nLL is empty.");
return h;
}
struct SLL *removeAfter(struct SLL *h,int key)
{
struct SLL *tmp,*p;
tmp=h;
if(h!=NULL)
{
while(tmp!=NULL && tmp->data!=key)
tmp=tmp->next;
if(tmp!=NULL)
{
if(tmp->next!=NULL)
{
p=tmp->next;
tmp->next=p->next;
p->next=NULL;
free(p);
}
else
printf("nGiven Node is the last Node.");
}
else
printf("nGiven key does not exist.");
//printf("ntmp->data=%d",tmp->dmpata);
//printf("nprev->data=%d",prev->data);
}
else
printf("nLL is empty.");
40. return h;
}
void display(struct SLL *h)
{
struct SLL *tmp;
tmp=h;
//modify to empty list
if(h!=NULL)
{
printf("nnttLinked List Contents..n");
while(tmp!=NULL)
{
printf("t%dn",tmp->data);
tmp=tmp->next;
}
}
else
{
printf("nLL is empty.");
}
}
int main()
{
struct SLL *head;
int ch,d,k;
head=NULL;
while(1)
{
printf("nnntttMENU");
printf("n1. Insert.n2. Insert After.n3. Remove.n4. Remove After.n5. Display.n6. Exit.");
printf("ntEnter Your Choice :: ");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("ntEnter Data : ");
scanf("%d",&d);
head=insertAtEnd(head,d);
break;
41. case 2:
printf("ntEnter Data : ");
scanf("%d",&d);
printf("ntEnter Key Data : ");
scanf("%d",&k);
head=insertAfter(head,k,d);
break;
case 3:
//head=removelast(head);
head=removefirst(head);
break;
case 4:
printf("ntEnter Key : ");
scanf("%d",&d);
head=removeAfter(head,d);
break;
case 5:
display(head);
break;
case 6:
//exit(0);
return 0;
break;
default:
printf("nttPlease enter correct choice....");
}
}
return 0;
}
Output Screenshot:
42. Conclusion:
Linked list is a dynamic data structure so it can grow and shrink at runtime by allocating and de
allocating memory.
References:
https://en.wikipedia.org/wiki/Linked_list
Post Lab Assignment:
Click on the following link and solve the problem and paste screenshot of score
https://www.geeksforgeeks.org/data-structure-gq/linked-list-gq/
43. PRACTICAL NO. 7
Problem Definition: Write a program that uses functions to perform the following:
a) Create a doubly linked list of integers.
b) Insert a given integer into the doubly linked list
c) Delete a given integer from the doubly linked list.
d) Display the contents of the above list after insertion and deletion
Compiler / Tool: Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
In a double linked list, every node has a link to its previous node and next node. So, we can traverse
forward by using the next field and can traverse backward by using the previous field. Every node
in a double linked list contains three fields and they are shown in the following figure
Here, 'link1' field is used to store the address of the previous node in the sequence, 'link2' field is
used to store the address of the next node in the sequence and 'data' field is used to store the actual
value of that node.
In a double linked list, the first node must be always pointed by head. Always the previous field
of the first node must be NULL. Always the next field of the last node must be NULL.
Algorithm:
Operations on Double Linked List
In a double linked list, we perform the following operations
1. Insertion
2. Deletion
44. 3. Display
Insertion
In a double linked list, the insertion operation can be performed in three ways as follows...
1. Inserting At Beginning of the list
2. Inserting At End of the list
3. Inserting At Specific location in the list
Inserting At Beginning of the list
We can use the following steps to insert a new node at the beginning of the double linked list...
● Step 1 - Create a newNode with given value and newNode → previous as NULL.
● Step 2 - Check whether list is Empty (head == NULL)
● Step 3 - If it is Empty then, assign NULL to newNode → next and newNode to head.
● Step 4 - If it is not Empty then, assign head to newNode → next and newNode to head.
Inserting At End of the list
We can use the following steps to insert a new node at the end of the double linked list...
● Step 1 - Create a newNode with given value and newNode → next as NULL.
● Step 2 - Check whether list is Empty (head == NULL)
● Step 3 - If it is Empty, then assign NULL to newNode → previous and newNode to head.
● Step 4 - If it is not Empty, then, define a node pointer temp and initialize with head.
● Step 5 - Keep moving the temp to its next node until it reaches to the last node in the list
(until temp → next is equal to NULL).
● Step 6 - Assign newNode to temp → next and temp to newNode → previous.
Inserting At Specific location in the list (After a Node)
We can use the following steps to insert a new node after a node in the double linked list...
● Step 1 - Create a newNode with a given value.
● Step 2 - Check whether list is Empty (head == NULL)
● Step 3 - If it is Empty then, assign NULL to both newNode → previous & newNode →
next and set newNode to head.
45. ● Step 4 - If it is not Empty then, define two node pointers temp1 & temp2 and initialize
temp1 with head.
● Step 5 - Keep moving the temp1 to its next node until it reaches the node after which we
want to insert the newNode (until temp1 → data is equal to location, here location is the
node value after which we want to insert the newNode).
● Step 6 - Every time check whether temp1 is reached to the last node. If it is reached to the
last node then display 'Given node is not found in the list!!! Insertion not possible!!!'
and terminate the function. Otherwise move the temp1 to next node.
● Step 7 - Assign temp1 → next to temp2, newNode to temp1 → next, temp1 to newNode
→ previous, temp2 to newNode → next and newNode to temp2 → previous.
Deletion
In a double linked list, the deletion operation can be performed in three ways as follows...
1. Deleting from Beginning of the list
2. Deleting from End of the list
3. Deleting a Specific Node
Deleting from Beginning of the list
We can use the following steps to delete a node from the beginning of the double linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is not Empty then, define a Node pointer 'temp' and initialize with head.
● Step 4 - Check whether list is having only one node (temp → previous is equal to temp
→ next)
● Step 5 - If it is TRUE, then set head to NULL and delete temp (Setting Empty list
conditions)
● Step 6 - If it is FALSE, then assign temp → next to head, NULL to head → previous
and delete temp.
Deleting from End of the list
We can use the following steps to delete a node from the end of the double linked list...
● Step 1 - Check whether list is Empty (head == NULL)
46. ● Step 2 - If it is Empty, then display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is not Empty then, define a Node pointer 'temp' and initialize with head.
● Step 4 - Check whether list has only one Node (temp → previous and temp → next both
are NULL)
● Step 5 - If it is TRUE, then assign NULL to head and delete temp. And terminate from
the function. (Setting Empty list condition)
● Step 6 - If it is FALSE, then keep moving temp until it reaches the last node in the list.
(until temp → next is equal to NULL)
● Step 7 - Assign NULL to temp → previous → next and delete temp.
Deleting a Specific Node from the list
We can use the following steps to delete a specific node from the double linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminates the function.
● Step 3 - If it is not Empty, then define a Node pointer 'temp' and initialize with head.
● Step 4 - Keep moving the temp until it reaches the exact node to be deleted or to the last
node.
● Step 5 - If it is reached to the last node, then display 'Given node not found in the list!
Deletion is not possible!!!' and terminate the function.
● Step 6 - If it is reached to the exact node which we want to delete, then check whether list
is having only one node or not
● Step 7 - If the list has only one node and that is the node which is to be deleted then set
head to NULL and delete temp (free(temp)).
● Step 8 - If the list contains multiple nodes, then check whether temp is the first node in the
list (temp == head).
● Step 9 - If temp is the first node, then move the head to the next node (head = head →
next), set head of previous to NULL (head → previous = NULL) and delete temp.
● Step 10 - If temp is not the first node, then check whether it is the last node in the list (temp
→ next == NULL).
● Step 11 - If temp is the last node then set temp of previous of next to NULL (temp →
previous → next = NULL) and delete temp (free(temp)).
● Step 12 - If temp is not the first node and not the last node, then set temp of previous of
next to temp of next (temp → previous → next = temp → next), temp of next of
previous to temp of previous (temp → next → previous = temp → previous) and delete
temp (free(temp)).
47. Displaying a Double Linked List
We can use the following steps to display the elements of a double linked list...
● Step 1 - Check whether list is Empty (head == NULL)
● Step 2 - If it is Empty, then display 'List is Empty!!!' and terminate the function.
● Step 3 - If it is not Empty, then define a Node pointer 'temp' and initialize with head.
● Step 4 - Display 'NULL <--- '.
● Step 5 - Keep displaying temp → data with an arrow (<===>) until temp reaches to the
last node
● Step 6 - Finally, display temp → data with an arrow pointing to NULL (temp → data --
-> NULL).
Program:
#include<stdio.h>
#include<stdlib.h>
struct DLL /* Global structure to create a node*/
{
int data;
struct DLL *next,*prev;
};
struct DLL *insertAtEnd(struct DLL *h,int d)
{
struct DLL *p,*tmp;
p=(struct DLL *)malloc(sizeof(struct DLL)); //creating a new node
p->data=d; //putting data into new node
p->next=NULL; //making new node point to null
p->prev=NULL; //Added for DLL
if(h==NULL)
{ // LL is empty
h=p;
}
else
{ //LL is not empty
tmp=h;
while(tmp->next!=NULL) //to traverse to the last node
tmp=tmp->next;
tmp->next=p;
48. p->prev=tmp; //Added for DLL
}
return h;
}
struct DLL *insertAtStart(struct DLL *h,int d)
{
struct DLL *p,*tmp;
p=(struct DLL *)malloc(sizeof(struct DLL)); //creating a new node
p->data=d; //putting data into new node
p->next=h;
p->prev=NULL;
if(h!=NULL)
h->prev=p;
h=p;
return h;
}
struct DLL *insertAfter(struct DLL *h,int key,int d)
{
struct DLL *p,*tmp;
p=(struct DLL *)malloc(sizeof(struct DLL)); //creating a new node
p->data=d; //putting data into new node
p->next=NULL; //making new node point to null
p->prev=NULL; //newly added statement
if(h==NULL)
{ // LL is empty
h=p;
}
else
{ //LL is not empty
tmp=h;
while(tmp!=NULL && tmp->data!=key ) //to traverse to the last node
tmp=tmp->next;
if(tmp!=NULL)
{
//tmp1=tmp->next;
49. p->next=tmp->next;
p->prev=tmp; //Additional
if(tmp->next!=NULL) //Additional
(tmp->next)->prev=p; //Additional
tmp->next=p;
}
else
printf("ntGiven Node %d does not exist in the Linked List.",key);
}
return h;
}
struct DLL *removelast(struct DLL *h)
{
struct DLL *tmp;
tmp=h;
if(h!=NULL)
{
if(h->next!=NULL)
{
while(tmp->next!=NULL)
tmp=tmp->next;
//after while loop, tmp will point to last node.
(tmp->prev)->next=NULL;
}
else
h=NULL;
free(tmp);
}
else
printf("nLL is empty.");
return h;
}
struct DLL *removeAfter(struct DLL *h,int key)
{
struct DLL *tmp,*p;
tmp=h;
if(h!=NULL)
50. {
while(tmp!=NULL && tmp->data!=key)
tmp=tmp->next;
if(tmp!=NULL)
{
if(tmp->next!=NULL)
{
p=tmp->next;
if(p->next!=NULL) //Additional
(p->next)->prev=tmp; //Additional
tmp->next=p->next;
p->next=NULL;
p->prev=NULL; //Additional
free(p);
}
else
printf("nGiven Node is the last Node.");
}
else
printf("nGiven key does not exist.");
}
else
printf("nLL is empty.");
return h;
}
void display(struct DLL *h)
{
struct DLL *tmp;
tmp=h;
if(h!=NULL)
{
printf("nnttLinked List Contents..n");
while(tmp!=NULL)
{
printf("t%dn",tmp->data);
tmp=tmp->next;
51. }
}
else
printf("nLL is empty.");
}
void displayRev(struct DLL *h)
{
struct DLL *tmp;
tmp=h;
if(h!=NULL)
{
printf("nnttLinked List Contents in Reverse Order..n");
while(tmp->next!=NULL)
tmp=tmp->next;
do
{
printf("t%dn",tmp->data);
tmp=tmp->prev;
}while(tmp!=NULL);
}
else
printf("nLL is empty.");
}
int main()
{
struct DLL *head;
int ch,d,k;
head=NULL;
while(1)
{
printf("nnntttMENU");
printf("n1. Insert.n2. Remove.n3. Remove After.n4. Display.n5. Exit.");
printf("ntEnter Your Choice :: ");
scanf("%d",&ch);
switch(ch)
{
52. case 1:
printf("ntEnter Data : ");
scanf("%d",&d);
head=insertAtEnd(head,d);
break;
case 2:
head=removelast(head);
break;
case 3:
printf("ntEnter Key : ");
scanf("%d",&k);
//printf("ntEnter Data : ");
//scanf("%d",&d);
head=removeAfter(head,k);
break;
case 4:
display(head);
displayRev(head);
break;
case 5:
//exit(0);
return 0;
break;
default:
printf("nttPlease enter correct choice....");
}
}
return 0;
}
Output Screenshot:
53. Conclusion:
A doubly linked list allows convenient access from a list node to the next node and also to the
preceding node on the list. The doubly linked list node accomplishes this in the obvious way by
storing two pointers: one to the node following it (as in the singly linked list), and a second pointer
to the node preceding it.
References:
https://en.wikipedia.org/wiki/Doubly_linked_list
Post Lab Assignment:
Q1. Write a program to reverse the data in a doubly linked list.
54. PRACTICAL NO. 8
Problem Definition: Write a program that uses functions to perform the following:
a) Create a binary search tree of integers.
b) Insert a given integer into the binary search tree
c) Delete a given integer from the binary search tree
d) Display the contents of the tree after insertion and deletion
Compiler / Tool: Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
In a binary tree, every node can have a maximum of two children but there is no need to maintain
the order of nodes based on their values. In a binary tree, the elements are arranged in the order
they arrive at the tree from top to bottom and left to right.
A binary tree has the following time complexities...
1. Search Operation - O(n)
2. Insertion Operation - O(1)
3. Deletion Operation - O(n)
To enhance the performance of binary trees, we use a special type of binary tree known as Binary
Search Tree. Binary search tree mainly focuses on the search operation in a binary tree. Binary
search tree can be defined as “Binary Search Tree is a binary tree in which every node contains
only smaller values in its left subtree and only larger values in its right subtree”.
In a binary search tree, all the nodes in the left subtree of any node contains smaller values and all
the nodes in the right subtree of any node contains larger values as shown in the following figure
55. Algorithm:
Operations on a Binary Search Tree
The following operations are performed on a binary search tree...
1. Search
2. Insertion
3. Deletion
Search Operation in BST
In a binary search tree, the search operation is performed with O(log n) time complexity. The
search operation is performed as follows...
● Step 1 - Read the search element from the user.
● Step 2 - Compare the search element with the value of the root node in the tree.
● Step 3 - If both are matched, then display "Given node is found!!!" and terminate the
function
● Step 4 - If both are not matched, then check whether the search element is smaller or larger
than that node value.
● Step 5 - If the search element is smaller, then continue the search process in the left subtree.
● Step 6- If the search element is larger, then continue the search process in the right subtree.
● Step 7 - Repeat the same until we find the exact element or until the search element is
compared with the leaf node
● Step 8 - If we reach the node having the value equal to the search value then display
"Element is found" and terminate the function.
● Step 9 - If we reach the leaf node and if it is also not matched with the search element, then
display "Element is not found" and terminate the function.
Insertion Operation in BST
In a binary search tree, the insertion operation is performed with O(log n) time complexity. In a
binary search tree, a new node is always inserted as a leaf node. The insertion operation is
performed as follows...
● Step 1 - Create a newNode with a given value and set its left and right to NULL.
● Step 2 - Check whether the tree is Empty.
● Step 3 - If the tree is Empty, then set root to newNode.
56. ● Step 4 - If the tree is Not Empty, then check whether the value of newNode is smaller or
larger than the node (here it is root node).
● Step 5 - If newNode is smaller than or equal to the node then move to its left child. If
newNode is larger than the node then move to its right child.
● Step 6- Repeat the above steps until we reach the leaf node (i.e., reaches to NULL).
● Step 7 - After reaching the leaf node, insert the newNode as left child if the newNode is
smaller or equal to that leaf node or else insert it as right child.
Deletion Operation in BST
In a binary search tree, the deletion operation is performed with O(log n) time complexity.
Deleting a node from the Binary search tree includes the following three cases...
● Case 1: Deleting a Leaf node (A node with no children)
● Case 2: Deleting a node with one child
● Case 3: Deleting a node with two children
Case 1: Deleting a leaf node
We use the following steps to delete a leaf node from BST...
● Step 1 - Find the node to be deleted using search operation
● Step 2 - Delete the node using free function (If it is a leaf) and terminate the function.
Case 2: Deleting a node with one child
We use the following steps to delete a node with one child from BST...
● Step 1 - Find the node to be deleted using search operation
● Step 2 - If it has only one child then create a link between its parent node and child node.
● Step 3 - Delete the node using free function and terminate the function.
Case 3: Deleting a node with two children
We use the following steps to delete a node with two children from BST...
● Step 1 - Find the node to be deleted using search operation
● Step 2 - If it has two children, then find the largest node in its left subtree (OR) the
smallest node in its right subtree.
● Step 3 - Swap both the deleting node and node which is found in the above step.
57. ● Step 4 - Then check whether deleting node came to case 1 or case 2 or else goto step 2
● Step 5 - If it comes to case 1, then delete using case 1 logic.
● Step 6- If it comes to case 2, then delete using case 2 logic.
● Step 7 - Repeat the same process until the node is deleted from the tree.
Example
Construct a Binary Search Tree by inserting the following sequence of numbers
10,12,5,4,20,8,7,15 and 13
Above elements are inserted into a Binary Search Tree as follows
Program:
#include<stdio.h>
#include<stdlib.h>
struct bstree
{
int data;
struct bstree *left,*right;
61. inorder(root);
break;
case 3:
printf("ntPre Order Traversal.");
preorder(root);
break;
case 4:
printf("ntPost Order Traversal.");
postorder(root);
break;
case 5:
printf("nEnter data :: ");
scanf("%d",&d);
p=search(root,d);
if(p==NULL)
printf("nGiven Key does not exist..");
else
printf("nGiven Key does exist..");
break;
case 6:
exit(0);
break;
}
}
}
Output Screenshot:
Conclusion:
A Binary Search Tree is a binary tree that additionally satisfies the binary search property. This
type of tree is similar to how a binary search works on an array. The number of elements to
compare decreases every time the search progresses.
63. PRACTICAL NO. 9
Problem Definition: Write a program for implementing to arrange a list of integers in ascending
order using Quick sort.
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
Quick sort is a fast sorting algorithm used to sort a list of elements. Quick sort algorithm was
invented by C. A. R. Hoare.
The quick sort algorithm attempts to separate the list of elements into two parts and then sort each
part recursively. That means it uses divide and conquer strategy. In quick sort, the partition of
the list is performed based on the element called pivot. Here the pivot element is one of the
elements in the list.
The list is divided into two partitions such that "all elements to the left of pivot are smaller than
the pivot and all elements to the right of pivot are greater than or equal to the pivot".
Algorithm:
In the Quick sort algorithm, partitioning of the list is performed using following steps...
● Step 1 - Consider the first element of the list as pivot (i.e., Element at first position in the
list).
● Step 2 - Define two variables i and j. Set i and j to first and last elements of the list
respectively.
● Step 3 - Increment i until list[i] > pivot then stop.
● Step 4 - Decrement j until list[j] < pivot then stop.
● Step 5 - If i < j then exchange list[i] and list[j].
● Step 6 - Repeat steps 3,4 & 5 until i > j.
● Step 7 - Exchange the pivot element with list[j] element.
Example:
66. a[j]=k;
}
}
a[low]=a[j];
a[j]=pivot;
return j;
}
void quicksort(int a[],int low,int high)
{
int p,i;
if(low<high)
{
printf("nnLow=%d and High=%d",low,high);
for(i=low;i<=high;i++)
printf("t%d",a[i]);
p=partition(a,low,high);
quicksort(a,low,p-1);
quicksort(a,p+1,high);
}
}
int main()
{
int a[20],n,i;
printf("n Enter Total NO of elements.");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("nEnter Element ::");
scanf("%d",&a[i]);
}
quicksort(a,0,n-1);
printf("ntSorted List...n");
for(i=0;i<n;i++)
printf("%dn",a[i]);
}
67. Output Screenshot:
Conclusion:
Quick Sort is an efficient divide-and-conquer algorithm. It divides a large list into two smaller sub-
lists based on a pivot chosen, into smaller and larger elements. Quick Sort then recursively does
this to the sub-lists finally producing a sorted list.
References:
https://en.wikipedia.org/wiki/Quicksort
Post Lab Assignment:
Q1. Write a program for implementing to arrange a list of integers in ascending order using
Selection sort.
Q2. Write a program for implementing to arrange a list of integers in ascending order using
Insertion sort.
68. PRACTICAL NO. 10
Problem Definition: Write a program to search a given integer in an array using Binary search.
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
Search is a process of finding a value in a list of values. In other words, searching is the process
of locating a given value position in a list of values.
Binary search algorithm finds a given element in a list of elements with O(log n) time complexity
where n is the total number of elements in the list. The binary search algorithm can be used with
only a sorted list of elements. That means the binary search is used only with a list of elements that
are already arranged in an order. The binary search can not be used for a list of elements arranged
in random order. This search process starts comparing the search element with the middle element
in the list. If both are matched, then the result is "element found". Otherwise, we check whether
the search element is smaller or larger than the middle element in the list. If the search element is
smaller, then we repeat the same process for the left sublist of the middle element. If the search
element is larger, then we repeat the same process for the right sublist of the middle element. We
repeat this process until we find the search element in the list or until we are left with a sublist of
only one element. And if that element also doesn't match with the search element, then the result
is "Element not found in the list".
Algorithm:
● Step 1 - Read the search element from the user.
● Step 2 - Find the middle element in the sorted list.
● Step 3 - Compare the search element with the middle element in the sorted list.
● Step 4 - If both are matched, then display "Given element is found!!!" and terminate the
function.
● Step 5 - If both are not matched, then check whether the search element is smaller or larger
than the middle element.
● Step 6 - If the search element is smaller than the middle element, repeat steps 2, 3, 4 and 5
for the left sublist of the middle element.
● Step 7 - If the search element is larger than the middle element, repeat steps 2, 3, 4 and 5
for the right sublist of the middle element.
● Step 8 - Repeat the same process until we find the search element in the list or until the
sublist contains only one element.
● Step 9 - If that element also doesn't match with the search element, then display "Element
is not found in the list!!!" and terminate the function.
Example:
70. }
int main()
{
int a[20],n,i,ch,k;
printf("nEnter Total no of elements :: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("nEnter Elements in Sorted Order..");
scanf("%d",&a[i]);
}
printf("nt Enter Key Element To search ::");
scanf("%d",&k);
i=binarySer(a,n,k);
if(i==-1)
printf("n Key Element does not exists..n");
else
printf("n Key Element Exist at location %dn",i);
}
Output Screenshot:
Conclusion:
Binary search is an efficient algorithm for finding an item from a sorted list of items. It works by
repeatedly dividing in half the portion of the list that could contain the item, until you've narrowed
down the possible locations to just one.
References:
https://en.wikipedia.org/wiki/Binary_search_algorithm
Post Lab Assignment:
Click on the following link and solve the problem and paste screenshot of score
https://quizizz.com/admin/quiz/5ba273301a89790019b9f723/binary-searches
71. PRACTICAL NO. 11
Problem Definition: We are given a graph with a source vertex in the graph. And we have to find
the shortest path from the source vertex to all other vertices of the graph.Write a program to find
the shortest path between two vertices of a graph using Dijkstra’s algorithm.
Compiler / Tool : Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
Dijkstra's algorithm allows us to find the shortest path between any two vertices of a graph.
It differs from the minimum spanning tree because the shortest distance between two vertices
might not include all the vertices of the graph.
Dijkstra's Algorithm works on the basis that any subpath B -> D of the shortest path A -> D
between vertices A and D is also the shortest path between vertices B and D.
Algorithm:
Step 1 : Create a set shortPath to store vertices that come in the way of the shortest path tree.
Step 2 : Initialize all distance values as INFINITE and assign distance values as 0 for source
vertex so that it is picked first.
Step 3 : Loop until all vertices of the graph are in the shortPath.
Step 3.1 : Take a new vertex that is not visited and is nearest.
Step 3.2 : Add this vertex to shortPath.
Step 3.3 : For all adjacent vertices of this vertex update distances. Now check every adjacent
vertex of V, if sum of distance of u and weight of edge is else update it.
72. Program:
#include<stdio.h>
#include<conio.h>
#define INFINITY 9999
#define MAX 10
void dijkstra(int G[MAX][MAX],int n,int startnode);
int main()
{
int G[MAX][MAX],i,j,n,u;
printf("Enter no. of vertices:");
scanf("%d",&n);
printf("nEnter the adjacency matrix:n");
for(i=0;i<n;i++)
for(j=0;j<n;j++)
scanf("%d",&G[i][j]);
printf("nEnter the starting node:");
scanf("%d",&u);
dijkstra(G,n,u);
return 0;
}
void dijkstra(int G[MAX][MAX],int n,int startnode)
{
int cost[MAX][MAX],distance[MAX],pred[MAX];
int visited[MAX],count,mindistance,nextnode,i,j;
//pred[] stores the predecessor of each node
//count gives the number of nodes seen so far
//create the cost matrix
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(G[i][j]==0)
cost[i][j]=INFINITY;
else
cost[i][j]=G[i][j];
//initialize pred[],distance[] and visited[]
for(i=0;i<n;i++)
{
distance[i]=cost[startnode][i];
pred[i]=startnode;
visited[i]=0;
}
distance[startnode]=0;
73. visited[startnode]=1;
count=1;
while(count<n-1)
{
mindistance=INFINITY;
//nextnode gives the node at minimum distance
for(i=0;i<n;i++)
if(distance[i]<mindistance&&!visited[i])
{
mindistance=distance[i];
nextnode=i;
}
//check if a better path exists through nextnode
visited[nextnode]=1;
for(i=0;i<n;i++)
if(!visited[i])
if(mindistance+cost[nextnode][i]<distance[i])
{
distance[i]=mindistance+cost[nextnode][i];
pred[i]=nextnode;
}
count++;
}
//print the path and distance of each node
for(i=0;i<n;i++)
if(i!=startnode)
{
printf("nDistance of node%d=%d",i,distance[i]);
printf("nPath=%d",i);
j=i;
do
{
j=pred[j];
printf("<-%d",j);
}while(j!=startnode);
}
}
Output Screenshot:
74. Conclusion:
Dijkstra’s Algorithm is useful for finding the shortest path in a weighted graph. In any graph G,
the shortest path from a source vertex to a destination vertex can be calculated using this algorithm.
References:
https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
Post Lab Assignment:
Q1.Click on the following link and solve the problem and paste screenshot of score
https://www.gatecseit.in/dijkstras-algorithm-multiple-choice-questions-and-answers-mcqs/
Q2.Write programs for implementing the following graph traversal algorithms:
a) Depth first traversal
b) Breadth first traversal
75. PRACTICAL NO. 12
Problem Definition: Write a program to implement all the functions of a dictionary (ADT) using
hashing.
Compiler / Tool: Turbo/Borland C compiler
https://www.onlinegdb.com/
Theory:
In all search techniques like linear search, binary search and search trees, the time required to
search an element depends on the total number of elements present in that data structure. In all
these search techniques, as the number of elements increases the time required to search an element
also increases linearly.
Hashing is another approach in which time required to search an element doesn't depend on the
total number of elements. Using hashing data structure, a given element is searched with constant
time complexity. Hashing is an effective way to reduce the number of comparisons to search an
element in a data structure.
Hashing is defined as “Hashing is the process of indexing and retrieving element (data) in a data
structure to provide a faster way of finding the element using a hash key”.
Here, the hash key is a value which provides the index value where the actual data is likely to be
stored in the data structure.
In this data structure, we use a concept called Hash table to store data. All the data values are
inserted into the hash table based on the hash key value. The hash key value is used to map the
data with an index in the hash table. And the hash key is generated for every data using a hash
function. That means every entry in the hash table is based on the hash key value generated using
the hash function.
Hash Table is defined as “Hash table is just an array which maps a key (data) into the data structure
with the help of hash function such that insertion, deletion and search operations are performed
with constant time complexity (i.e. O(1)).”
Hash tables are used to perform insertion, deletion and search operations very quickly in a data
structure. Using hash table concept, insertion, deletion, and search operations are accomplished in
constant time complexity. Generally, every hash table makes use of a function called hash
function to map the data into the hash table.
A hash function is defined as follows...
76. Hash function is a function which takes a piece of data (i.e. key) as input and produces an integer
(i.e. hash value) as output which maps the data to a particular index in the hash table.
Basic concept of hashing and hash table is shown in the following figure.
Algorithm:
Linear Probing algorithm to insert key in the hash table
1. Retrieve key k
2. Compute hash function h[k]= k %size of the table
3. If hash table is empty at the computed hash value place
then insert key at h[k]
else
we need to find another empty place in the hash table to insert the key in the table
3.1 Use linear probing to compute the hash value of the key again , in linear probing we
generally keep adding some constant value to the computed hash value .
3.2 If hash table place is empty then insert key at h[k] and exit
else Repeat 3.1 step again .
Program:
#include<stdio.h>
#include<stdlib.h>
/* to store a data (consisting of key and value) in hash table array */
struct item
{
int key;
int value;
};
/* each hash table item has a flag (status) and data (consisting of key and value) */
struct hashtable_item
77. {
int flag;
/*
* flag = 0 : data does not exist
* flag = 1 : data exists
* flag = 2 : data existed at least once
*/
struct item *data;
};
struct hashtable_item *array;
int size = 0;
int max = 10;
/* initializing hash table array */
void init_array()
{
int i;
for (i = 0; i < max; i++)
{
array[i].flag = 0;
array[i].data = NULL;
}
}
/* to every key, it will generate a corresponding index */
int hashcode(int key)
{
return (key % max);
}
/* to insert an element in the hash table */
void insert(int key, int value)
{
int index = hashcode(key);
int i = index;
78. /* creating new item to insert in the hash table array */
struct item *new_item = (struct item*) malloc(sizeof(struct item));
new_item->key = key;
new_item->value = value;
/* probing through the array until we reach an empty space */
while (array[i].flag == 1)
{
if (array[i].data->key == key)
{
/* case where already existing key matches the given key */
printf("n Key already exists, hence updating its value n");
array[i].data->value = value;
return;
}
i = (i + 1) % max;
if (i == index)
{
printf("n Hash table is full, cannot insert any more item n");
return;
}
}
array[i].flag = 1;
array[i].data = new_item;
size++;
printf("n Key (%d) has been inserted n", key);
}
/* to remove an element from the hash table */
void remove_element(int key)
{
int index = hashcode(key);
79. int i = index;
/* probing through array until we reach an empty space where not even once an element had
been present */
while (array[i].flag != 0)
{
if (array[i].flag == 1 && array[i].data->key == key )
{
// case when data key matches the given key
array[i].flag = 2;
array[i].data = NULL;
size--;
printf("n Key (%d) has been removed n", key);
return;
}
i = (i + 1) % max;
if (i == index)
{
break;
}
}
printf("n This key does not exist n");
}
/* to display all the elements of hash table */
void display()
{
int i;
for (i = 0; i < max; i++)
{
struct item *current = (struct item*) array[i].data;
if (current == NULL)
{
80. printf("n Array[%d] has no elements n", i);
}
else
{
printf("n Array[%d] has elements -: n %d (key) and %d(value) ", i, current->key,
current->value);
}
}
}
int size_of_hashtable()
{
return size;
}
void main()
{
int choice, key, value, n, c;
clrscr();
array = (struct hashtable_item*) malloc(max * sizeof(struct hashtable_item*));
init_array();
do {
printf("Implementation of Hash Table in C with Linear Probing nn");
printf("MENU-: n1.Inserting item in the Hashtable"
"n2.Removing item from the Hashtable"
"n3.Check the size of Hashtable"
"n4.Display Hashtable"
"nn Please enter your choice-:");
scanf("%d", &choice);
switch(choice)
{
case 1:
printf("Inserting element in Hashtablen");
81. printf("Enter key and value-:t");
scanf("%d %d", &key, &value);
insert(key, value);
break;
case 2:
printf("Deleting in Hashtable n Enter the key to delete-:");
scanf("%d", &key);
remove_element(key);
break;
case 3:
n = size_of_hashtable();
printf("Size of Hashtable is-:%dn", n);
break;
case 4:
display();
break;
default:
printf("Wrong Inputn");
}
printf("n Do you want to continue-:(press 1 for yes)t");
scanf("%d", &c);
}while(c == 1);
getch();
82. }
Output Screenshot:
Conclusion:
Hashing is the function or routine used to assign the key values to each entity in the database.
Using hashing, we can easily access or search the values from the database.
References:
https://en.wikipedia.org/wiki/Hash_function
Post Lab Assignment:
Q1.Click on the following link and solve the problem and paste screenshot of score
https://www.geeksforgeeks.org/data-structure-gq/hash-gq/