Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
17 views

3rd Sem Data Structure & Algorithm

Uploaded by

Dhruv Vashishth
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views

3rd Sem Data Structure & Algorithm

Uploaded by

Dhruv Vashishth
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 103

Data Structure &

Algorithm

Ved Parkash
Associate Professor, CSE
 A computer program is a collection of instructions to
perform a specific task. For this, a computer program
may need to store data, retrieve data, and perform
computations on the data.
 Data Structure is a way of collecting and organising data
in such a way that we can perform operations on these
data in an effective way. For example, we have some data
which has, player's name "Virat" and age 26. Here "Virat"
is of String data type and 26 is of integer data type.
We can organize this data as a record like Player record,
which will have both player's name and age in it. Now we
can collect and store player's records in a file or database
as a data structure. For example: "Dhoni" 30, "Gambhir"
31, "Sehwag" 33
 In simple language, Data Structures are structures
programmed to store ordered data, so that various
operations can be performed on it easily. It represents
the knowledge of data to be organized in memory. It
should be designed and implemented in such a way
that it reduces the complexity and increases the
efficiency.
 As we have discussed above, anything that can store

data can be called as a data structure, hence Integer,


Float, Boolean, Char etc, all are data structures. They
are known as Primitive Data Structures.
Then we also have some complex Data Structures,
which are used to store large and connected data.
Some example of Abstract Data Structure are :
 Linked List
 Tree
 Graph
 Stack, Queue etc.

All these data structures allow us to perform different


operations on data. We select these data structures
based on which type of operation is required. 
The data structures can also be classified on the basis of the following characteristics:

 Linear
In Linear data structures,the data items are arranged in a linear sequence.
Example: Array
 Non-Linear
In Non-Linear data structures,the data items are not in sequence.
Example: Tree, Graph
 Homogeneous
In homogeneous data structures,all the elements are of same type. Example: Array
 Non-Homogeneous
In Non-Homogeneous data structure, the elements may or may not be of the same
type. Example: Structures
 Static
Static data structures are those whose sizes and structures associated memory
locations are fixed, at compile time. Example: Array
 Dynamic
Dynamic structures are those which expands or shrinks depending upon the program
need and its execution. Also, their associated memory locations changes.
Example: Linked List created using pointers
What is an Algorithm ?
An algorithm is a finite set of instructions or logic, written in
order, to accomplish a certain predefined task. Algorithm is not
the complete code or program, it is just the core logic(solution)
of a problem, which can be expressed either as an informal
high level description as pseudocode or using a flowchart.
Every Algorithm must satisfy the following properties:
 Input- There should be 0 or more inputs supplied externally to

the algorithm.
 Output- There should be atleast 1 output obtained.

 Definiteness- Every step of the algorithm should be clear and

well defined.
 Finiteness- The algorithm should have finite number of steps.

 Correctness- Every step of the algorithm must generate a

correct output.
Data structures are used to hold data while algorithms
are used to solve the problem using that data.
An algorithm is said to be efficient and fast, if it takes
less time to execute and consumes less memory space.
The performance of an algorithm is measured on the
basis of following properties :
 Time Complexity
 Space Complexity
Space Complexity
Its the amount of memory space required by the algorithm,
during the course of its execution. Space complexity must be
taken seriously for multi-user systems and in situations where
limited memory is available.

An algorithm generally requires space for following components :


 Instruction Space: Its the space required to store the

executable version of the program. This space is fixed, but


varies depending upon the number of lines of code in the
program.
 Data Space: Its the space required to store all the constants

and variables(including temporary variables) value.


 Environment Space: Its the space required to store the

environment information needed to resume the suspended


function.
Time Complexity
 Time Complexity is a way to represent the amount of

time required by the program to run till its completion.


It's generally a good practice to try to keep the time
required minimum, so that our algorithm completes
it's execution in the minimum time possible.
Qualities of a good algorithm
 Input and output should be defined precisely.
 Each step in the algorithm should be clear and

unambiguous.
 Algorithms should be most effective among many

different ways to solve a problem.


 An algorithm shouldn't include computer code.

Instead, the algorithm should be written in such a way


that it can be used in different programming
languages.
Basic Terminology:
 Data are simply values or set of values.
 Data item refers to a single unit of values.
 Data items that are divided into sub items are called

group items; those that are not are called elementary


items. For example employee name (group item) may
be divided but the social security no. (elementary
item)
 Collection of data are frequently organized into a

hierarchy of fields, records and files


Attributes: Name Age Mob. Address
Values: Amit 21 ---- ---------
Data Structure operations:
 Traversing
 Searching
 Inserting
 Deleting
 Sorting
 Merging
(Traversing a Linear Array) Here LA is a Linear array with
lower bound LB and upper bound UB. This algorithm
traverses LA applying an operation PROCESS to each
element of LA.
1. [Initialize counter] set K:=LB.
2. Repeat step 3 and 4 while K<=UB.
3. [visit element] Apply PROCESS to LA[K].
4. [Increase counter] set K:=K+1.
[End of step 2 Loop]
5. Exit.
(Inserting into a Linear Array) INSERT(LA,N,K,ITEM)
Here LA is a linear array with N elements and K is a
positive integer such that K<=N. This algorithm insert
an element ITEM into Kth position in LA.
1. [Initialize counter] set J:=N
2. Repeat step 3 and 4 while J>=K.
3. [Move Jth element downword] set LA[J+1]:=LA[J]
4. [Decrease counter] set J:=J-1.
[End of step 2 Loop]
5. [Insert element] set LA[k]=ITEM
6. [Reset N] set N:=N+1.
7. Exit
(Deleting from a Linear Array) DELETE (LA,N,K,ITEM)
Here LA is a Linear array with N elements and K is
positive integer such that K<=N. this algorithm
deletes the Kth element from LA
1. Set ITEM:=LA[K]
2. Repeat for J=K to N-1:
3. [Move J + 1st element upward] Set LA[J]:=LA[J+1]
4. [End of Loop]
5. [Reset the number N of elements in LA] set N:=N-1
6. Exit
(Linear Search) A Linear array DATA with N elements and a specific
ITEM of information are given. This algorithm finds the location LOC
of ITEM in the array DATA or set LOC=0.

1. [initialize] set k:=1 and LOC:=0.


2. Repeat step 3 and 4 while LOC=0 and K<=N.
3. If ITEM=DATA[K], Then: set LOC:=K.
4. Set K:=K+1.
[End of step 2 loop]
5. [Successful ?]
If LOC=0, then:
write: ITEM is not in the array DATA.
Else:
write: LOC is the location of ITEM
[End of IF structure]
6. Exit
(Binary Search) BINARY (DATA, LB, UB, ITEM, LOC)
Here DATA is a sorted array with lower bound LB and upper bound UB, and ITEM is a
given item of information. The variables BEG, END, AND MID denote respectively,
the beginning, end and middle location of a segment of element of DATA. This
algorithm finds the location LOC of ITEM in DATA or set LOC=NULL.
1. [Initialize segment variables]

Set BEG:=LB, END:=UB and MID=INT((BEG+END)/2).


2. Repeat step 3 and 4 while BEG<=END and DATA[MID]≠ITEM
3. If ITEM<DATA[MID], THEN:
Set END:=MID-1.
Else:
Set BEG:=MID+1
[End of if structure]
4. Set MID:=INT((BEG+END)/2)
[END OF step2 loop]
5. If DATA[MID]=ITEM, then:
Set LOC:=MID
Else:
Set LOC:=NULL
[End of if structure]
2. Exit
The major difference between static and dynamic memory allocations are:

Static Memory Allocation Dynamic Memory Allocation

In this case, variables get allocated In this case, variables get allocated only if
permanently your program unit gets active

Allocation is done before program Allocation is done during program


execution execution

It uses the data structure called stack for It uses the data structure called heap for
implementing static allocation implementing dynamic allocation

Less efficient More efficient

There is memory reusability and memory


There is no memory reusability
can be freed when not required
Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()
Since C is a structured language, it has some fixed rules for programming. One of
it includes changing the size of an array. An array is collection of items stored at
continuous memory locations.

 As it can be seen that the length (size) of the array above made is 9. But what if
there is a requirement to change this length (size). For Example,
 If there is a situation where only 5 elements are needed to be entered in this

array. In this case, the remaining 4 indices are just wasting memory in this array.
So there is a requirement to lessen the length (size) of the array from 9 to 5.
 Take another situation. In this, there is an array of 9 elements with all 9 indices

filled. But there is a need to enter 3 more elements in this array. In this case 3
indices more are required. So the length (size) of the array needs to be changed
from 9 to 12.
 This procedure is referred to as Dynamic Memory Allocation in C.
 malloc()

If the allocation succeeds, a void pointer to the


allocated memory is returned or NULL is returned if
there is insufficient memory available. To return a
pointer to a type other than void, use a type cast on
the return value.

If it is unable to find the requested amount of memory,


malloc() function returns NULL.

Syntax : ptr=(cast-type*)malloc(byte-size)
eg.      ptr = (int *)malloc(100 * sizeof (int));
 calloc()

allocates a contiguous block of memory large enough to


hold n elements of size bytes each. The allocated region is
initialized to zero.

Initialization : malloc() does not initialize the memory


allocated, while calloc() initializes the allocated memory
to ZERO.

Syntax : ptr=(cast-type*)calloc(n,element-size);
 Why does malloc() return a void*?

It’s because malloc() has no idea which type of object we


want to put in that memory.
 free()
Dynamically allocated memory with either calloc() or malloc()
does not get return on its own. The programmer must use
free() explicitly to release space.

syntax : free(ptr);
This statement cause the space in memory pointer by ptr to
be deallocated.
 realloc()

If the previously allocated memory is insufficient or more


than sufficient. Then, you can change memory size previously
allocated using realloc().

Syntax:  ptr=realloc(ptr,newsize);
Here, ptr is reallocated with size of newsize.
 Stack
A stack is an Abstract Data Type (ADT), commonly used
in most programming languages. It is named stack as it
behaves like a real-world stack, for example – a deck of
cards or a pile of plates, etc. At any given time, we can
only access the top element of a stack.
This feature makes it LIFO data structure. LIFO stands for
Last-in-first-out. Here, the element which is placed
(inserted or added) last, is accessed first. In stack
terminology, insertion operation is
called PUSH operation and removal operation is
called POP operation.
 Push Operation
The process of putting a new data element onto stack is
known as a Push Operation. Push operation involves a
series of steps −
 Step 1 − Checks if the stack is full.
 Step 2 − If the stack is full, produces an error and exit.
 Step 3 − If the stack is not full, increments top to point

next empty space.


 Step 4 − Adds data element to the stack location,

where top is pointing.


 Step 5 − Returns success.
 PUSH(STACK, TOP, MAXSTK, ITEM)

This procedure pushes an ITEM onto a stack


1. [Stack already filled?]
If TOP=MAXSTK, then: print: OVERFLOW, an Return
2. Set TOP:=TOP+1
3. Set STACK[TOP]:=ITEM [Insert TOP in new TOP
position]
4. Return
 Pop Operation
Accessing the content while removing it from the stack, is
known as a Pop Operation. In an array implementation of pop()
operation, the data element is not actually removed,
instead top is decremented to a lower position in the stack to
point to the next value. But in linked-list implementation, pop()
actually removes data element and deallocates memory space.
 A Pop operation may involve the following steps −
 Step 1 − Checks if the stack is empty.
 Step 2 − If the stack is empty, produces an error and exit.
 Step 3 − If the stack is not empty, accesses the data element

at which top is pointing.
 Step 4 − Decreases the value of top by 1.
 Step 5 − Returns success.
 POP (STACK, TOP, ITEM)
This procedure delete the top element of STACK and
assign it to the variable ITEM.

1. [Stack has an item to be removed ?]


if TOP=0, then: Print: UNDERFLOW, and Return.
2. Set ITEM:=STACK[TOP]
3. Set TOP:=TOP-1. [Decrease TOP by 1]
4. Return.
Arithmetic notation: The way to write arithmetic
expression is known as a notation. 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 −
 Infix Notation
 Prefix (Polish) Notation
 Postfix (Reverse-Polish) Notation
 These notations are named as how they use operator

in expression.
Infix Notation
 We write expression in infix notation, e.g. a - b + c,

where operators are used in-between operands. It is


easy for us humans to read, write, and speak in infix
notation but the same does not go well with
computing devices. An algorithm to process infix
notation could be difficult and costly in terms of time
and space consumption.
Prefix Notation
 In this notation, operator is prefixed to operands, i.e.

operator is written ahead of operands. For


example, +ab. This is equivalent to its infix notation a +
b. Prefix notation is also known as Polish Notation.
Postfix Notation
 This notation style is known as Reversed Polish

Notation. In this notation style, the operator


is postfixed to the operands i.e., the operator is
written after the operands. For example, ab+. This is
equivalent to its infix notation a + b.
Sr.No. Operator Precedence Associativity

1 Exponentiation ^ Highest Right Associative

2 Multiplication ( ∗ ) Second Highest Left Associative


& Division ( / )

3 Addition ( + ) & Lowest Left Associative


Subtraction ( − )
Sr.No. Infix Notation Prefix Notation Postfix Notation

1 a+b +ab ab+

2 (a + b) ∗ c ∗+abc ab+c∗

3 a ∗ (b + c) ∗a+bc abc+∗

4 a/b+c/d +/ab/cd ab/cd/+

5 (a + b) ∗ (c + d) ∗+ab+cd ab+cd+∗

6 ((a + b) ∗ c) - d -∗+abcd ab+c∗d-


 Infix to Postfix conversion
 A * (B + D) / E – F * ( G + H / K )

 A * [B D +] / E – F * ( G + [H K /] )

 [A B D + *] / E – F * [ G H K / +]

 [A B D + * E /] – [F G H K / + *]

 [A B D + * E / F G H K / + * -]
 Algorithm for Evaluation of postfix expression:
This algorithm finds the VALUE of arithmetic expression P written
in postfix notation.
1. Add a right parenthesis “)” at the end of P. [This act as a sentinel]

2. Scan P from left to right and repeat step 3 and 4 for each
element of P until the sentinel “)” is encountered.
3. If an operand is encountered, put it on STACK.
4. IF an operator Ꚛ is encountered, then:
(a) remove the two top element of STACK, where A is the top
element and B is the next-to-top element.
(b) Evaluate B Ꚛ A
© place the result of (b) on STACK.
[end of If structure]
[end of step 2 loop]
5. Set VALUE equal to the top element on STACK.
6. Exit.
 P: 5, 6, 2, +, *, 12, 4, /, -
P: 5, 6, 2, +, *, 12, 4, /, -, )
Symbol Scanned STACK
5 5
6 5, 6
2 5, 6, 2
+ 5, 8
* 40
12 40, 12
4 40, 12, 4
/ 40, 3
- 37
)
 Conversion infix to postfix using stack:
 Q: A + ( B * C – ( D / E ^ F ) * G ) * H

Symbol STACK Expression P


Scanned
A ( A
+ (+ A
( (+( A
B (+( AB
* (+(* AB
C (+(* ABC
- (+(- ABC*
( (+(-( ABC*
D (+(-( ABC*D
/ (+(-(/ ABC*D
E (+(-(/ ABC*DE
^ (+(-(/^ ABC*DE
F (+(-(/^ ABC*DEF
) (+(- ABC*DEF^/
* (+(-* ABC*DEF^/
Algorithm to convert Infix To Postfix
 Let, Q is an arithmetic expression written in infix notation. This
algorithm finds the equivalent postfix expression P.
1. Push “(“onto Stack, and add “)” to the end of Q.
2. Scan Q from left to right and repeat Step 3 to 6 for each element of Q
until the Stack is empty.
3. If an operand is encountered, add it to P.
4. If a left parenthesis is encountered, push it onto Stack.
5. If an operator is encountered ,then:
◦ Repeatedly pop from Stack and add to P each operator (on the top of
Stack) which has the same precedence as or higher precedence than
operator.
◦ Add operator to Stack.
[End of If]
6. If a right parenthesis is encountered ,then:
◦ Repeatedly pop from Stack and add to P each operator (on the top of
Stack) until a left parenthesis is encountered.
◦ Remove the left Parenthesis.
[End of If]
[End of STEP 2 LOOP]
 EXIT.
 Advantage of Postfix Expression over Infix Expression
 An infix expression is difficult for the machine to know

and keep track of 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.
Application of Stack:
 Stacks can be used for expression evaluation.
 Expression Conversion:

An expression can be represented in prefix, postfix or


infix notation. Stack can be used to convert one form of
expression to another.
 Parenthesis Checking:

Stack is used to check the proper opening and closing of


parenthesis.
String Reversal:
Stack is used to reverse a string. We push the characters
of string one by one into stack and then pop character
from stack.
 Memory management:
The assignment of memory takes place in contiguous
memory blocks. We call this stack memory allocation
because the assignment takes place in the function call
stack. The size of the memory to be allocated is known
to the compiler. When a function is called, its variables
get memory allocated on the stack. When the function
call is completed, the memory for the variables is
released. All this happens with the help of some
predefined routines in the compiler. The user does not
have to worry about memory allocation and release of
stack variables.
 Backtracking Procedure −
Backtracking is one of the algorithm designing
technique. For that purpose, we dive into some way, if
that way is not efficient, we come back to the previous
state and go into some other paths. To get back from
current state, we need to store the previous state. For
that purpose, we need stack. Some examples of
backtracking is finding the solution for Knight Tour
problem or N-Queen Problem etc.
 Function Call:
 Another great use of stack is during the function call

and return process. When we call a function from one


other function, that function call statement may not be
the first statement. After calling the function, we also
have to come back from the function area to the place,
where we have left our control. So we want to resume
our task, not restart. For that reason, we store the
address of the program counter into the stack, then go
to the function body to execute it. After completion of
the execution, it pops out the address from stack and
assign it into the program counter to resume the task
again.
 Quick Sorting:
 Consider the above list A with n=12 elements. The
algorithm begin by pushing the boundary values 1 and
12 of A onto the stack to yield
 LOWER: 1UPPER: 12

In order to apply the reduction step, the algorithm first


removes the top values 1 and 12 from the stack, leaving
LOWER: emptyUPPER: empty
And then apply the reduction step to the corresponding
list A[1], A[2],……A[12].
LOWER: 1, 6 UPPER: 4, 12
In order to apply the reduction step again, the algorithm
removes the top values 6 and 12 from the stack

LOWER: 1 UPPER: 4
 (Quicksort) This algorithm sort an array A with N
elements.
Step 1: [Initialize] TOP=NULL
Step 2: [Push boundary values of A onto stacks when A
has 2 or more elements.]
If N>1, then: TOP=TOP+1, LOWER [1] =1, UPPER[1] = N
Step 3: Repeat step 4 to 7 while TOP != NULL
Step 4: [Pop sublist from stacks]
Set BEG=LOWER[TOP], END=UPPER[TOP]
TOP=TOP-1
Step 5: Call QUICK(A,N,BEG,ENG,LOC)
Step 6: [Push left sublist onto stacks when it has 2 or
more elements]
If BEG < LOC – 1, THEN:
TOP=TOP + 1, LOWER[TOP] = BEG,
UPPER[TOP]=LOC – 1.
[End of If]
Step 7 [Push right sublist onto stacks when it has 2 or
more elements]
If LOC + 1 < END, then:
Top=Top + 1, LOWER[TOP]=LOC+1,
UPPER[TOP]=END.
[End of If]
[End of step 3 loop]
Step 8 Exit.
 QUICK(A, N, BEG, END, LOC)
Here A is an array with N elements. Parameters BEG and
END contains the boundary values of the sublist of A to
which this procedure applies. LOC keep track of the
position of the first element A[BEG] of the sublist
during the procedure. The local variables LEFT and
RIGHT will contain the boundary values of the list of
elements that have not been scanned.
1. [initialize] Set LEFT:=BEG, RIGHT:=END AND LOC=BEG.
2. [Scan from right to left]
(a) Repeat while A[LOC]<=A[RIGHT] and LOC !=RIGHT:
RIGHT:=RIGHT – 1
[END of loop]
(b) If LOC=RIGHT, THEN: Return
© If A[LOC]>A[RIGHT], then:
(i) [Interchange A[LOC] and A[RIGHT]]
TEMP:=A[LOC], A[LOC]:=A[RIGHT]
A[RIGHT]:=TEMP
(ii) Set LOC:=RIGHT
(iii) Go to step 3
[End of If structure]
3. [Scan from Left to right]

(a) Repeat while A[LEFT]<=A[LOC] and LEFT!=LOC


LEFT:=LEFT + 1
[End of Loop]
(b) If LOC=LEFT, then: return
© If A[LEFT]>A[LOC], then
(i) [Interchange A[LEFT] and A[LOC]]
TEMP:=A[LOC], A[LOC]:=A[LEFT]
A[LEFT]:=TEMP
(ii) Set LOC:=LEFT
(iii) Go to step 2
[End of If]
 Queue:- A queue is a linear list of elements in which
deletion can take place only at one end , called the
front, and insertion can take place only at the other end
called the rear. This makes queue as FIFO(First in First
Out) data structure, which means that element inserted
first will be removed first. A good example of a queue is
any queue of consumers for a resource where the
consumer that came first is served first. 
 In a Linear queue, once the queue is completely full, it's not
possible to insert more elements. Even if we dequeue the queue to
remove some of the elements, until the queue is reset, no new
elements can be inserted. 

 Circular Queue is also a linear data structure, which follows the


principle of FIFO(First In First Out), but instead of ending the queue
at the last position, it again starts from the first position after the
last, hence making the queue behave like a circular data structure.

 Application of Circular Queue:


Below we have some common real-world examples where circular
queues are used:
1. Computer controlled Traffic Signal System uses circular
queue.
2. CPU scheduling and Memory management.
 QINSERT(QUEUE, N, FRONT, REAR, ITEM)
This procedure insert an element ITEM into a queue.
1. [Queue already filled?]

if FRONT=1 and REAR=N, or if FRONT=REAR+1, Then:


write OVERFLOW, and Return
2. [find new value of REAR]
If FRONT:=NULL, Then: [Queue initially empty]
Set FRONT:=1 and REAR:=1
Else if REAR=N, then: set REAR:=1.
Else:
Set REAR:=REAR+1
[END OF if STRUCTURE]
3. Set QUEUE[REAR]:=ITEM
4. Return.
 QDELETE(QUEUE, N, FRONT, REAR, ITEM)
This procedure delete an element from a queue and assign it to the
variable ITEM.
1. [Queue already empty?]
If FRONT:=NULL, then: Write: UNDERFLOW and Return
2. Set ITEM:=QUEUE[FRONT]
3. [Find new value of FRONT.]
If FRONT=REAR, then:
set FRONT:=NULL and REAR:=NULL.
else if FRONT=N, then:
set FRONT:=1
ELSE:
SET FRONT:=FRONT+1.
[End of If structure]
4. Return.
DEQUES (Double ended queue):
Deque or Double Ended Queue is a type of queue in which insertion
and removal of elements can be performed from either from the
front or rear. Thus, it does not follow FIFO rule (First In First Out).
Representation of Deque

Types of Deque:
 Input Restricted Deque

In this deque, input is restricted at a single end but allows deletion


at both the ends.
 Output Restricted Deque

In this deque, output is restricted at a single end but allows


insertion at both the ends.
 Operations on a Deque:
Insert Elements at Front
 First we check if the queue is full. If its not full we

insert an element at front end by following the given


conditions :
 If the queue is empty then intialize front and rear to 0.

Both will point to the first element.

Else we decrement front and insert the element. Since


we are using circular array, we have to keep in mind
that if front is equal to 0 then instead of decreasing it
by 1 we make it equal to SIZE-1.
Insert Elements at back
Again we check if the queue is full. If its not full we insert an element at back by following
the given conditions:
If the queue is empty then intialize front and rear to 0. Both will point to the first element.
Else we increment rear and insert the element. Since we are using circular array, we have
to keep in mind that if rear is equal to SIZE-1 then instead of increasing it by 1 we make it
equal to 0.
Delete First Element
In order to do this, we first check if the queue is empty. If its not
then delete the front element by following the given
conditions :
If only one element is present we once again make front and
rear equal to -1.
Else we increment front. But we have to keep in mind that if
front is equal to SIZE-1 then instead of increasing it by 1 we
make it equal to 0.
 Delete Last Element
 In order to do this, we again first check if the queue is

empty. If its not then we delete the last element by


following the given conditions :
 If only one element is present we make front and rear

equal to -1.
 Else we decrement rear. But we have to keep in mind

that if rear is equal to 0 then instead of decreasing it by


1 we make it equal to SIZE-1.
Applications of Deque Data Structure
 In undo operations on software.
 To store history in browsers.
 For implementing both stacks and queues.

Priority queues:
A priority queue is a collection of elements such that each element
has been assigned a priority and such that the order in which
elements are deleted and processed comes from the following rules:
1. An element of higher priority is processed before any element of
lower priority.
2. Two elements with the same priority are processed according to the
order in which they were added to the queue.
A prototype of a priority queue is a timesharing system: programs of
higher priority are processed first, and program with the same
priority form a standard queue.
 Application of Stack:
The Stack is Last In First Out (LIFO) data structure. This data structure has some
important applications in different aspect. These are like below −

 Expression Handling & Expression evaluation −


◦ Infix to Postfix or Infix to Prefix Conversion −
◦ The stack can be used to convert some infix expression into its postfix equivalent, or
prefix equivalent. These postfix or prefix notations are used in computers to express
some expressions. These expressions are not so much familiar to the infix expression,
but they have some great advantages also. We do not need to maintain operator
ordering, and parenthesis.
◦ Postfix or Prefix Evaluation −
◦ After converting into prefix or postfix notations, we have to evaluate the expression to
get the result. For that purpose, also we need the help of stack data structure.

 Backtracking Procedure −
 Backtracking is one of the algorithm designing technique. For that purpose,
we dive into some way, if that way is not efficient, we come back to the
previous state and go into some other paths. To get back from current state,
we need to store the previous state. For that purpose, we need stack. Some
examples of backtracking is finding the solution for Knight Tour problem or N-
Queen Problem etc.
 Function Call Process:
 Another great use of stack is during the function call

and return process. When we call a function from one


other function, that function call statement may not be
the first statement. After calling the function, we also
have to come back from the function area to the place,
where we have left our control. So we want to resume
our task, not restart. For that reason, we store the
address of the program counter into the stack, then go
to the function body to execute it. After completion of
the execution, it pops out the address from stack and
assign it into the program counter to resume the task
again.
 Reverse string:
The simplest task a stack could be used for is reversing a
string. Each letter in a string is pushed in and then
popped off thus reversing the string.
 Depth First Search:

A more complex task is recursive descent (top-down


depth first) parsing in Natural Language Processing. In
this task, the program traverses a tree following a path
starting from the top most node all the way down to a
terminal node trying to match a path in a given grammar.
As it traverses, the tree the path is saved in a stack which
records each movement that is made. (This is an
oversimplification of tree traversal in syntactic parsing
and recognition
 Parenthesis Checking
Stack is used to check the proper opening and closing of
parenthesis.
Application of queue:
 Implementation of a queue is also an important application

of data structure. Nowadays computer handles multiuser,


multiprogramming environment and time-sharing
environment. In this environment a system(computer)
handles several jobs at a time, to handle these jobs the
concept of a queue is used.
 To implement printer spooler so that jobs can be printed in

the order of their arrival.


 Round robin scheduling technique is implemented using

queue
 All types of customer service(like railway reservation)

centers are designed using the concept of queues.


 When a resource is shared among multiple consumers.
Examples include CPU scheduling, Disk Scheduling.
  When data is transferred asynchronously (data not

necessarily received at same rate as sent) between two


processes. Examples include IO Buffers, pipes, file IO,
etc.
 Breadth First Search:

In breadth-first search, the program starts at the top


node then moves down a level in the tree and searches
across all sister nodes before continuing to the next level
of depth
Applications of circular queue: 
 Traffic light functioning is the best example for 

circular queues. The colors in the traffic light follow a


circular pattern.
 In page replacement algorithms, a circular list of pages

is maintained and when a page needs to be replaced,


the page in the front of the queue will be chosen.
Applications of deque:
 Pallindrome checker.
 A-steal job scheduling algorithm
Applications of Priority Queue:
 Prim's algorithm implementation can be done using

priority queues.
 Dijkstra's shortest path algorithm implementation can

be done using priority queues.


 A* Search algorithm implementation can be done

using priority queues.


 Priority queues are used to sort heaps.
 Priority queues are used in operating system for load

balancing and interrupt handling.
 Priority queues are used in huffman codes for data

compression.
 In traffic light, depending upon the traffic, the colors

will be given priority.


Key Differences Between Array and Linked List 
1. An array is the data structure that contains a collection of
similar type data elements whereas the Linked list is
considered as a non-primitive data structure contains a
collection of unordered linked elements known as nodes. 
2. In the array the elements belong to indexes, i.e., if you
want to get into the fourth element you have to write the
variable name with its index or location within the square
bracket while in a linked list though, you have to start from
the head and work your way through until you get to the
fourth element. 
3. Accessing an element in an array is fast, while Linked list
takes linear time, so it is quite a bit slower. 
4. Operations like insertion and deletion in arrays consume a
lot of time. On the other hand, the performance of these
operations in Linked lists are fast. 
 5. Arrays are of fixed size. In contrast, Linked lists are
dynamic and flexible and can expand and contract its
size. 
6. In an array, memory is assigned during compile time
while in a Linked list it is allocated during execution or
runtime. 
7. Elements are stored consecutively in arrays whereas it
is stored randomly in Linked lists. 
8. The requirement of memory is less due to actual data
being stored within the index in the array. As against,
there is a need for more memory in Linked Lists due to
storage of additional next and previous referencing
elements. 
9. In addition memory utilization is inefficient in the array.
Conversely, memory utilization is efficient in the linked
list. 
 (1) The size of the arrays is fixed: So we must know the
upper limit on the number of elements in advance.
Also, generally, the allocated memory is equal to the
upper limit irrespective of the usage, and in practical
uses, the upper limit is rarely reached. 
 (2) Inserting a new element in an array of elements is
expensive because a room has to be created for the
new elements and to create room existing elements
have to be shifted. 
 For example, suppose we maintain a sorted list of IDs in
an array id[ ]. 
 id[ ] = [1000, 1010, 1050, 2000, 2040, …..]. 
 And if we want to insert a new ID 1005, then to
maintain the sorted order, we have to move all the
elements after 1000 (excluding 1000). 
 Deletion is also expensive with arrays until unless some
special techniques are used. For example, to delete
1010 in id[], everything after 1010 has to be moved. 
 So Linked list provides the following two advantages

over arrays 
1) Dynamic size 
2) Ease of insertion/deletion 

 Linked lists have following drawbacks: 


1) Random access is not allowed. We have to access
elements sequentially starting from the first node. So
we cannot do a binary search with linked lists. 
2) Extra memory space for a pointer is required with
each element of the list. 
Linked List Data Structure
 A linked list is a linear data structure, in which the

elements are not stored at contiguous memory


locations. The elements in a linked list are linked using
pointers as shown in the below image:

In simple words, a linked list consists of nodes where


each node contains a data field and a reference(link) to
the next node in the list. They are used in situations
when there is need to allocate memory dynamically that
is during runtime of a program
Types of Linked List
Following are the various types of linked list.
 Simple Linked List − Item navigation is forward only.

 Doubly Linked List − Items can be navigated forward and

backward.
 Circular Linked List − Last item contains link of the first

element as next and the first element has a link to the last
element as previous.
Basic Operations:
Following are the basic operations supported by a list.
 Insertion − Adds an element at the beginning of the list.

 Deletion − Deletes an element at the beginning of the list.

 Display − Displays the complete list.

 Search − Searches an element using the given key.


 Delete − Deletes an element using the given key.
 Insertion operation :

First, create a node using the same structure and find the
location where it has to be inserted

Imagine that we are inserting a node B (NewNode),


between A (LeftNode) and C (RightNode). Then point B.next to
C−

NewNode.next −> RightNode;


LeftNode.next −> NewNode;
Delete Operation:

LeftNode.next −> TargetNode.next;


TargetNode.next −> NULL;
 (Traversing a linked list) let LIST be a linked list in
memory. This algorithm traverse LIST, applying an
operation PROCESS to each element of LIST. The
variable PTR points to the node currently being
processed.
 1. Set PTR:=START [Initialize pointer PTR]
 2. Repeat step 3 and 4 while PTR!= NULL
 3. Apply PROCESS to INFO[PTR]
 4. Set PTR:=LINK[PTR]
 [End of step 2 Loop]
 5. Exit.
 Searching a linked list
SEARCH(INFO, LINK, START, ITEM, LOC)
LIST is a linked list in memory. This algorithm finds the
location LOC of the node where ITEM first appear in LIST, or
set LOC=NULL.
1. Set PTR:=START

2. Repeat step 3 while PTR!= NULL:

3. If ITEM=INFO[PTR], then:

Set LOC:=PTR, and Exit.


Else:
Set PTR:=LINK[PTR]
[End of If structure]
[End of step2 loop]
4. [Search is unsuccessful] Set LOC:=NULL
5. Exit.
Searching into a sorted linked list
SRCHSL(INFO, LINK, START,ITEM, LOC)
LIST is a sorted list in memory. This algorithm finds the location LOC
of the node where ITEM first appears in LIST, or set LOC=NULL.
1. Set PTR:=START.

2. Repeat Step 3 while PTR!=NULL:

3. If ITEM>INFO[PTR], then:
Set PTR:=LINK[PTR]
Else if ITEM=INFO[PTR], then:
set LOC:=PTR, and Exit [search is successful]
Else:
Set LOC:=NULL, and Exit
[End of If structure]
[End of step2 loop]
4. Set LOC:=NULL
5. Exit.
 What do you mean by- (a) Memory Allocation (b)
Garbage Collection (c) Overflow & Underflow
 a) Memory Allocation-

Whenever a new node is created, memory is allocated by


the system. This memory is taken from list of those
memory locations which are free i.e. not allocated. This
list is called AVAIL List. Similarly, whenever a node is
deleted, the deleted space becomes reusable and is
added to the list of unused space i.e. to AVAIL List. This
unused space can be used in future for memory
allocation.

Memory allocation is of two types-

1. Static Memory Allocation


2. Dynamic Memory Allocation
 1. Static Memory Allocation:

When memory is allocated during compilation time, it is called


‘Static Memory Allocation’. This memory is fixed and cannot
be increased or decreased after allocation. If more memory is
allocated than requirement, then memory is wasted. If less
memory is allocated than requirement, then program will not
run successfully. So exact memory requirements must be
known in advance.

2. Dynamic Memory Allocation:

When memory is allocated during run/execution time, it is


called ‘Dynamic Memory Allocation’. This memory is not fixed
and is allocated according to our requirements. Thus in it
there is no wastage of memory. So there is no need to know
exact memory requirements in advance.
 (b) Garbage Collection-

Whenever a node is deleted, some memory space becomes


reusable. This memory space should be available for future
use. One way to do this is to immediately insert the free space
into availability list. But this method may be time consuming
for the operating system. So another method is used which is
called ‘Garbage Collection’. This method is described below: In
this method the OS collects the deleted space time to time
onto the availability list. This process happens in two steps. In
first step, the OS goes through all the lists and tags all those
cells which are currently being used. In the second step, the
OS goes through all the lists again and collects untagged space
and adds this collected space to availability list. The garbage
collection may occur when small amount of free space is left
in the system or no free space is left in the system or when
CPU is idle and has time to do the garbage collection.
 (c) Overflow & Underflow-

Overflow happens at the time of insertion. If we have


to insert new space into the data structure, but there is
no free space i.e. availability list is empty, then this
situation is called ‘Overflow’. The programmer can
handle this situation by printing the message of
OVERFLOW.

Underflow happens at the time of deletion. If we have


to delete data from the data structure, but there is no
data in the data structure i.e. data structure is empty,
then this situation is called ‘Underflow’. The
programmer can handle this situation by printing the
message of UNDERFLOW.
1.ptr = (struct node *) malloc(sizeof(struct node *));  
2.            ptr → data = item   

1.ptr->next = head;  
Insertion after a given node:

You might also like