1. CS 331 DATA STRUCTURES
Dr. Chandran Saravanan
Asst. Prof., Dept. of C.S.E.,
N.I.T. Durgapur
Dr.cs1973@gmail.com
2. Online References
• UC Berkeley video course on data structures
(http://academicearth.org/online-college-courses/)
• Dictionary of Algorithms and Data Structures http://nist.gov/dads/
• http://www.cse.unr.edu/~bebis/CS308/
• Data structures course
http://www.cs.auckland.ac.nz/software/AlgAnim/ds_ToC.html
• Data structure tutorials
http://courses.cs.vt.edu/~csonline/DataStructures/Lessons/index.ht
ml
• An Examination of Data Structures from .NET perspective
http://msdn.microsoft.com/en-us/library/aa289148(VS.71).aspx
• Schaffer, C. Data Structures and Algorithm Analysis
http://people.cs.vt.edu/~shaffer/Book/C++3e20110915.pdf
3. Introduction
• Structuring the Data / Sorting the Data /
Organizing data
• To find, update, add, and delete data efficiently
• Different kinds of data structures are suitable for
different kinds of applications
• Example: B-Trees – for databases, hash tables –
for compiler design
4. Basic Principles
• Data structures are based on the ability of a
computer to fetch and store data at any place in
its memory, specified by an address and
manipulated by the program.
• The record and array data structures are based
on computing the addresses of data items with
arithmetic operations
• The linked data structures are based on storing
addresses of data items within the structure itself
5. Basic Principles cont…
• The implementation of a data structure requires a
set of procedures that create and manipulate
instances of that structure.
• The efficiency of a data structure cannot be
analyzed separately from those operations.
• This observation motivates the theoretical
concept of an abstract data type, a data structure
that is defined indirectly by the operations that
may be performed on it, and the mathematical
properties of those operations (including their
space and time cost)
6. Language support
• Most assembly languages / low-level languages, such as BCPL(Basic
Combined Programming Language), lack support for data
structures.
• Many high-level programming languages, and some higher-level
assembly languages, such as MASM, on the other hand, have
special syntax or other built-in support for certain data structures,
such as vectors (one-dimensional arrays) in the C language or multi-
dimensional arrays in Pascal.
• Most programming languages feature some sorts of library
mechanism that allows data structure implementations to be
reused by different programs.
• Modern languages usually come with standard libraries that
implement the most common data structures. Examples are the
C++ Standard Template Library, the Java Collections Framework, and
Microsoft's .NET Framework.
7. Selecting a Data Structure
• Analyze your problem to determine the basic
operations that must be supported.
– Examples of basic operations include inserting a data
item into the data structure, deleting a data item from
the data structure, and finding a specified data item.
• Quantify the resource constraints for each
operation.
• Select the data structure that best meets these
requirements.
8. Selecting a Data Structure
• Are all data items inserted into the data structure at
the beginning, or are insertions interspersed with other
operations?
– Static applications (where the data are loaded at the
beginning and never change) typically require only simpler
data structures to get an efficient implementation than do
dynamic applications.
• Can data items be deleted? If so, this will probably
make the implementation more complicated.
• Are all data items processed in some well-defined
order, or is search for specific data items allowed?
– “Random access” search generally requires more complex
data structures.
9. Problem, Algorithm, Program
• A problem is a task to be performed (Function / Maths)
• An algorithm is a method or a process followed to solve a
problem
• A problem can be solved by many different algorithms
• To design an algorithm that is easy to understand, code,
and debug.
• To design an algorithm that makes efficient use of the
computer’s resources.
• A solution is said to be efficient if it solves the problem
within the required resource constraints.
• A computer program as an instance, or concrete
representation, of an algorithm in some programming
language.
10. Analysis of Algorithms
• In computer science, the analysis of algorithms is
the determination of the number of resources
(such as time and storage) necessary to execute
them.
• Most algorithms are designed to work with inputs
of arbitrary length. Usually the efficiency or
running time of an algorithm is stated as a
function relating the input length to the number
of steps (time complexity) or storage locations
(space complexity)
11. Analysis of Algorithms cont…
• Algorithm analysis is an important part of a broader
computational complexity theory, which provides
theoretical estimates for the resources needed by any
algorithm which solves a given computational problem.
These estimates provide an insight into reasonable
directions of search for efficient algorithms.
• Big O notation, omega notation and theta notation are
used
• A model of computation may be defined in terms of an
abstract computer, e.g., Turing machine, and/or by
postulating that certain operations are executed in unit
time.
12. Cost and Benefits
• A data structure requires a certain amount of
space for each data item it stores,
• a certain amount of time to perform a single
basic operation,
• and a certain amount of programming effort.
• Each problem has constraints on available space
and time
• Only after a careful analysis the problem’s
characteristics the best data structure for the task
is determined
13. Example 1
• A bank must support many types of transactions
with its customers, but we will examine a simple
model where customers wish to open accounts,
close accounts, and add money or withdraw
money from accounts.
• Time constraints - Customers are willing to wait
many minutes while accounts are created or
deleted but are typically not willing to wait more
than a brief time for individual account
transactions such as a deposit or withdrawal.
14. Uniform and Logarithmic
• the uniform cost model, also called uniform-
cost measurement, assigns a constant cost to
every machine operation, regardless of the
size of the numbers involved
• the logarithmic cost model, also called
logarithmic-cost measurement, assigns a cost
to every machine operation proportional to
the number of bits involved - cumbersome to
use
15. Run-time analysis
• Run-time analysis is a theoretical classification
that estimates and anticipates the increase in
running time (or run-time) of an algorithm as
its input size (usually denoted as n) increases.
• Run-time efficiency is a topic of great interest
in computer science: A program can take
seconds, hours or even years to finish
executing, depending on which algorithm it
implements.
16. Shortcomings of empirical metrics
• algorithms are platform-independent
• algorithm can be implemented in an arbitrary
programming language on an arbitrary computer
running an arbitrary operating system
• a program that looks up a specific entry in a sorted list
of size n.
• Suppose this program were implemented on Computer
A, a state-of-the-art machine, using a linear search
algorithm, and on Computer B, a much slower
machine, using a binary search algorithm.
• Benchmark testing on the two computers running their
respective programs will be error
17. Big O
• For a given input size n greater than some n0
and a constant c, the running time of that
algorithm will never be larger than c × f(n).
• This concept is frequently expressed using Big
O notation. For example, since the run-time of
insertion sort grows quadratically as its input
size increases, insertion sort can be said to be
of order O(n²).
18. Big O cont …
• Big O notation is a convenient way to express
the worst-case scenario for a given algorithm,
although it can also be used to express the
average-case
• for example, the worst-case scenario for
quicksort is O(n²), but the average-case run-
time is O(n log n).
19. Big O cont …
• O() notation focuses on the largest term and
ignores constants
• Largest term will dominate eventually for large
enough n.
• Constants depend on “irrelevant” things like
machine speed, architecture, etc.
20. Evaluating run-time complexity
• The run-time complexity for the worst-case scenario of
a given algorithm can be evaluated by examining the
structure of the algorithm and making some
simplifying assumptions.
• A given computer will take a discrete amount of time
to execute each of the instructions involved with
carrying out this algorithm.
• The specific amount of time to carry out a given
instruction will vary depending on which instruction is
being executed and which computer is executing it, but
on a conventional computer, this amount will be
deterministic.
21. Example
1 get a positive integer from input
2 if n > 10
3 print "This might take a while..."
4 for i = 1 to n
5 for j = 1 to i
6 print i * j
7 print "Done!"
22. Example cont …
• In the algorithm above, steps 1, 2 and 7 will only be run
once.
• For a worst-case evaluation, it should be assumed that
step 3 will be run as well.
• Thus the total amount of time to run steps 1-3 and step
7 is: T1+T2+T3+T7
• The loops in steps 4, 5 and 6 are trickier to evaluate.
The outer loop test in step 4 will execute ( n + 1 ) times
(note that an extra step is required to terminate the for
loop, hence n + 1 and not n executions), which will
consume T4( n + 1 ) time.
23. Example cont …
• The inner loop, on the other hand, is governed
by the value of i, which iterates from 1 to n.
• On the first pass through the outer loop, j
iterates from 1 to 1:
• The inner loop makes one pass, so running the
inner loop body (step 6) consumes T6 time,
and the inner loop test (step 5) consumes 2T5
time.
24. Example cont …
• During the next pass through the outer loop, j
iterates from 1 to 2: the inner loop makes two
passes, so running the inner loop body (step
6) consumes 2T6 time, and the inner loop test
(step 5) consumes 3T5 time.
• Altogether, the total time required to run the
inner loop body can be expressed as an
arithmetic progression:
– T6+2T6+3T6+…+(n-1)T6+nT6
25. Example cont …
• which can be factored as
• T6 1 + 2 + 3 + ⋯ + n − 1 + 𝑛 =
𝑇6[
1
2
(𝑛2
+ 𝑛)]
• = 𝑂 𝑛2
• Rule 1: Drop low order terms.
• Rule 2: Drop constant factors
• Rule 3: Addition and multiplication identities
29. Data Structure Applications
1. How does Google find web pages quickly using
keywords?
2. How to send messages to other computers / mobile
phones faster?
3. How can a subsequence of DNA be quickly found
within the genome?
4. How does your operating system track which memory
is free?
5. How the computer games determine the scene
changes?
30. Data Structure ?
It’s an agreement about:
• how to store a collection of objects in memory,
• what operations we can perform on that data,
• the algorithms for those operations, and
• how time and space efficient those algorithms are.
Ex. Vector in C
• Stores objects sequentially in memory
• Can access, change, insert or delete objects
• Algorithms for insert & delete will shift items as needed
• Space: O(n), Access/change = O(1), Insert/delete = O(n)
31. Exercises
• Find the maximum value, second maximum
value, third largest value, middle value in an
(unsorted) array.
• Design a spelling checker program
32. Arrays
• Arrays a kind of data structure that can store a
fixed-size sequential collection of elements of
the same type.
• An array is used to store a collection of data,
but it is often more useful to think of an array
as a collection of variables of the same type.
• Elements of arrays are accessed by using index
or subscripts.
34. 2D Array Column / Row Major Order
• Elements of two-dimensional arrays are stored
in two ways:-
– Column major order: Elements are stored column
by column, i.e. all elements of first column are
stored, and then all elements of second column
stored and so on.
– Row major order: all elements of first row are
stored, and then all elements of second row
stored and so on.
35.
36. Address Calculation
• Since array elements are stored in contiguous
memory locations, the computer needs to not to
know the address of every element but the
address of only first element.
• The address of first element is called base
address of array.
• Given the address of first element, address of any
other element is calculated using the formula:-
Loc (arr [k]) =base (arr) + w * k
• Where, k is the index of array, w is the number of
bytes for one element,
37. Example
• Suppose that array arr is declared as integers
with size 20 and its first element is stored at
address 1000.
• Calculate the address of 4th element of array
when the index of the array starts from 0.
• Here, base address=1000, k=3, w=2.
• Thus, loc(arr[3])=1000 + 2*3=1006
38. Address calculation in 2D Array
• Column major order:-
• Loc(arr[i][j])=base(arr) + w (m *j + i)
• Row major order:-
• Loc(arr[i][j])=base(arr) + w (n*i + j)
• Where array is m x n matrix, lbc is the lower
bound of column, lbr is the lower bound of
row.
39. Applications of Arrays
• used to represent strings, stacks and queues
• form the basis for several more complex data
structures, such as heaps, hash tables,
and vlists
• one-dimensional character arrays are used to
store null-terminated strings ('0')
40. Character Strings in C
An array of characters to hold a string
char blue[26];
char yellow[26] = {'y', 'e', 'l', 'l', 'o', 'w', '0'};
char orange[26] = "orange";
char gray[] = {'g', 'r', 'a', 'y', '0'};
char salmon[] = "salmon";
41. The string terminator null character 0 is included at the end
of the string
char lemon[26] = "custard";
lemon = "steak sauce"; /* Fails! */
Can change one character at a time
char name[] = "bob";
name[0] = 'r';
42. • It is possible to initialize an array using a string that has
more characters than the specified size.
• This is not a good thing. The larger string will not override
the previously specified size of the array, and you will get a
compile-time warning.
• Since the original array size remains, any part of the string
that exceeds that original size is being written to a memory
location that was not allocated for it.
char greet[5]=”Good Morning”;
43. Array as Parameter
• In passing an array as a parameter to a
function it is passed as a reference parameter.
• What is actually passed is the address of its
first element.
• Though an array is passed as a reference
parameter an & is not used to denote a
reference parameter but by appending [].
44. Three ways of passing array
• Formal parameters as a sized array
– void myFunction (int param [10]) { . . . }
• Formal parameters as an unsized array
– void myFunction (int param []) { . . . }
• Formal parameters as a pointer
– void myFunction (int *param) { . . . }
45. Example
double getAverage(int arr[], int size)
{ int i; double avg;
double sum = 0;
for (i = 0; i < size; ++i) {
sum += arr[i];
}
avg = sum / size; return avg;
}
46. Example
#include <stdio.h>
double getAverage(int arr[], int size);
int main () {
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
avg = getAverage( balance, 5 ) ;
printf( "Average value is: %f ", avg );
return 0;
}
47. Ordered List
• A singly linked list in which values are inserted
in either
• ascending or descending order is called an
ordered singly linked list.
48. Example
#include<stdio.h>
#include<conio.h>
void main() {
int a[100],i,n,pos,x;
clrscr();
printf("enter how many value in arrayn");
scanf("%d",&n);
printf("Enter %d value in Ascending Ordern",n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("Which value to be insert ->");
scanf("%d",&x);
49. Example
for(i=0;i<n;i++)
if(x<a[i]) { pos =i; break; }
for(i=n;i>=pos;i--) a[i]= a[i-1];
a[pos]=x; printf("Your Exist List is :n ");
for(i=0;i<n;i++) printf("%5d",a[i]);
printf("nnAfter Insert the list is :n ");
for(i=0;i<=n;i++)
printf("%5d",a[i]);
getch();
}
50. Sparse Matrix and Vectors
• sparse matrix or sparse array is a matrix in
which most of the elements are zero.
• A matrix is typically stored as a two-
dimensional array. Each entry in the array
represents an element ai,j of the matrix and is
accessed by the two indices i and j.
• Conventionally, i is the row index, numbered
from top to bottom, and j is the column index,
numbered from left to right.
51. Sparse Matrix and Vectors
• For an m × n matrix, the amount of memory
required to store the matrix in this format is
proportional to m × n.
• In the case of a sparse matrix, substantial
memory requirement reductions can be realized
by storing only the non-zero entries.
• Depending on the number and distribution of the
non-zero entries, different data structures can be
used and yield huge savings in memory when
compared to the basic approach.
52. Sparse Matrix and Vectors Formats
• Those that support efficient modification,
such as DOK (Dictionary of keys), LIL (List of
lists), or COO (Coordinate list). These are
typically used to construct the matrices.
• Those that support efficient access and matrix
operations, such as CSR (Compressed Sparse
Row) or CSC (Compressed Sparse Column).
53. DOK, LIL, COO
• DOK consists of a dictionary that maps (row,
column)-pairs to the value of the elements.
Elements that are missing from the dictionary are
taken to be zero.
• LIL stores one list per row, with each entry
containing the column index and the value.
• COO stores a list of (row, column, value) tuples.
Ideally, the entries are sorted (by row index, then
column index) to improve random access times.
54. CSR, CRS or Yale format
• The compressed sparse row (CSR) or compressed row
storage (CRS) format represents a matrix M by three (one-
dimensional) arrays, that respectively contain nonzero
values, the extents of rows, and column indices.
• The CSR format stores a sparse m × n matrix M in row form
using three (one-dimensional) arrays (A, IA, JA)
• A is of length NNZ and holds all the nonzero entries of M in
left-to-right top-to-bottom ("row-major") order
• Array IA is of length m + 1 and defined by recursive
definition – pointer to row I
• The third array, JA, contains the column index in M of each
element of A and hence is of length NNZ as well.
55. Compressed sparse column (CSC or
CCS)
• CSC is similar to CSR except that values are
read first by column, a row index is stored for
each value, and column pointers are stored.
• I.e. CSC is (val, row_ind, col_ptr), where val is
an array of the (top-to-bottom, then left-to-
right) non-zero values of the matrix;
• row_ind is the row indices corresponding to
the values; and, col_ptr is the list
of val indexes where each column starts.
56. Stacks
• A stack is a container of objects that are inserted and
removed according to the Last-In First-Out (LIFO) principle.
• In the pushdown stacks only two operations are allowed:
push the item into the stack, and pop the item out of the
stack.
• A stack is a limited access data structure - elements can be
added and removed from the stack only at the top.
• Push adds an item to the top of the stack, pop removes the
item from the top.
• A helpful analogy is to think of a stack of books; you can
remove only the top book, also you can add a new book on
the top.
57.
58. Applications
• A stack is a recursive data structure. Here is a
structural definition of a Stack:
• a stack is either empty or it consists of a top and
the rest which is a stack;
• The simplest application of a stack is to reverse a
word. You push a given word to stack - letter by
letter - and then pop letters from the stack.
• Another application is an "undo" mechanism in
text editors; this operation is accomplished by
keeping all text changes in a stack.
59. • Language processing: space for parameters
and local variables is created internally using a
stack.
• compiler's syntax check for matching braces is
implemented by using stack.
• support for recursion
60. Infix
• Operators are written in-between their operands.
• This is the usual way we write expressions. An
expression such as A * ( B + C ) / D is usually taken
to mean something like:
• "First add B and C together, then multiply the
result by A, then divide by D to give the final
answer.“
• To avoid ambiguity (operators precedence and
associativity rules) with infix notations prefix and
postfix notations are introduced
61. Prefix and Postfix
Prefix:- (also called as polish notation)
• Operators are written before their operands. The
expressions given above are equivalent to
• 5 + 7 => + 5 7, / * A + B C D
Postfix:- (also called as reverse polish notation)
• Operators are written after their operands. The
infix expression given above is equivalent to
• 5 + 7 => 5 7 +, A B C + * D /
62. Infix to Prefix / Postfix
• Prefix "operators are evaluated left-to-right",
they use values to their right, and if these
values themselves involve computations then
this changes the order that the operators have
to be evaluated in. / * A + B C D
• Operators are written after their operands.
The infix expression given above is equivalent
to A B C + * D /
63. Example
Infix Postfix Prefix
( (A * B) + (C / D) ) ( (A B *) (C D /) +) (+ (* A B) (/ C D) )
((A * (B + C) ) / D) ( (A (B C +) *) D /) (/ (* A (+ B C) ) D)
(A * (B + (C / D) ) ) (A (B (C D /) +) *) (* A (+ B (/ C D) ) )
2, 3, *, 5, 4, *, +, 9, –
6, 5, 4, *, +, 9, –
6, 20, +, 9, –
26, 9, –
17
64. Order of Operation
• Paranthesis () {} []
• Exponents – right to left
• Multiplication and division – left to right
• Addition and subtraction – left to right
• Examples
4 + 6 * 2 = 16
2 * 6 / 2 – 3 + 7 = 10
65. Psuedo Code evaluate Postfix
EvaluatePostfix (exp)
{
create stack s
for i<-0 to length(exp)-1
{
if (exp[i] is operand)
Push (exp[i])
elseif (exp[i] is operator)
{
op2<-pop()
op1<-pop()
res<-perform(exp[i],op1,op2)
push res;
}
}
return top of stack;
}
66. Psuedo Code evaluate Prefix
• Right to left
• If operand Push operands
• If operator pop two operands and evaluate
• Repeat until all operands and operators
evaluated
67. Assignments
• Write a ‘C’ program to read infix form and
convert to prefix form using Arrays
• Write a ‘C’ program to read infix form and
convert to postfix form using Arrays
• Write a ‘C’ program to evaluate infix expression
using Arrays
• Write a ‘C’ program to evaluate prefix expression
using Arrays
• Write a ‘C’ program to evaluate postfix
expression using Arrays
68. Queues
• Queue is an abstract data structure, similar to
Stacks.
• Unlike stacks, a queue is open at both its ends.
One end is always used to insert data (enqueue)
and the other is used to remove data (dequeue).
• Queue follows First-In-First-Out methodology,
i.e., the data item stored first will be accessed
first.
• Example: Queues at the ticket windows and bus-
stops, railway station, cinema hall, etc.
69.
70. Operations on Queue
1. Create – new queue created
2. Add − enqueue() − add to the queue
3. Delete − dequeue() − remove from the queue
4. Full − Checks if the queue is full
5. Empty − Checks if the queue is empty
• Queues maintain two data pointers,
– front and rear (size of the queue)
71. Enqueue Operation
Step 1 − Check if the queue is full.
Step 2 − If the queue is full, produce overflow
error and exit.
Step 3 − If the queue is not full, increment
rear pointer to point the next empty space.
Step 4 − Add data element to the queue
location, where the rear is pointing.
Step 5 − return success.
72. Dequeue Operation
Step 1 − Check if the queue is empty.
Step 2 − If the queue is empty, produce
underflow error and exit.
Step 3 − If the queue is not empty, access the
data where front is pointing.
Step 4 − Increment front pointer to point to the
next available data element.
Step 5 − Return success.
73. Applications of Queue
• Serving requests on a single shared resource,
like a printer, CPU task scheduling etc.
• In real life, Call Center phone systems will use
Queues, to hold people calling them in an
order, until a service representative is free.
• Handling of interrupts in real-time systems.
The interrupts are handled in the same order
as they arrive, First come first served.
74. Circular Queue
• In a normal Queue Data Structure, we can insert
elements until queue becomes full.
• But once if queue becomes full, we can not insert
the next element until all the elements are
deleted from the queue.
• Consider the following situation after deleting
three elements from the queue.
• This situation also says that Queue is Full and we
can not insert the new element because, 'rear' is
still at last position.
75. Circular Queue
• In above situation,
even though we have empty
positions in the queue we can
not make use of them to
insert new element.
• This is the major problem in normal queue
data structure. To overcome this problem we
use circular queue data structure.
76.
77. Circular Queue Applications
• Memory Management: The unused memory
locations in the case of ordinary queues can be
utilized in circular queues.
• Traffic system: In computer controlled traffic
system, circular queues are used to switch on the
traffic lights one by one repeatedly as per the
time set.
• CPU Scheduling: Operating systems often
maintain a queue of processes that are ready to
execute or that are waiting for a particular event
to occur.
78. Implementation of Circular Queue
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 operation selected by the user on circular queue.
79. enQueue(value) – Inserting element
Step 1: Check whether 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.
80. deQueue() – Deleting element
Step 1: Check whether 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
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 TRUE, then set
both front and rear to '-1' (front = rear = -1).
81. display() - Displays elements
• Step 1: Check whether 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.
82. Double Ended Queue (Dequeue)
• Double Ended Queue is also a Queue data
structure in which the insertion and deletion
operations are performed at both the ends
(front and rear).
• That means, we can insert at both front and
rear positions and can delete from both front
and rear positions.
83. d-queues
• Double Ended Queue can be represented in TWO ways,
those are as follows...
– Input Restricted Double Ended Queue
– Output Restricted Double Ended Queue
• In input restricted double ended queue, the insertion
operation is performed at only one end and deletion
operation is performed at both the ends.
• In output restricted double ended queue, the deletion
operation is performed at only one end and insertion
operation is performed at both the ends.
84.
85. Priority Queues
• Each element in the queue has a “priority”
associated with it.
• In a priority queue, an element with high
priority is served before an element with low
priority.
• If two elements have the same priority, they
are served according to their order in the
queue.
86. A typical priority queue supports following operations.
insert(item, priority): Inserts an item with given priority.
getHighestPriority(): Returns the highest priority item.
deleteHighestPriority(): Removes the highest priority
item.
87. Linked List
• A linked list is a way to store a collection of
elements. Like an array these can be character
or integers. Each element in a linked list is
stored in the form of a node.
88. Head and Node
• A node is a collection of two sub-elements or
parts. A data part that stores the element and
a next part that stores the link to the next node.
• A linked list is formed when many such nodes are
linked together to form a chain. Each node points
to the next node present in the order. The first
node is always used as a reference to traverse the
list and is called HEAD. The last node points
to NULL.
89. Example
• Suppose a spy who wishes to give a codebook to another spy by
putting it in a post office box and then giving him the key. However,
the book is too thick to fit in a single post office box, so instead he
divides the book into two halves and purchases two post office
boxes. In the first box, he puts the first half of the book and a key to
the second box, and in the second box he puts the second half of
the book. She then gives Bob a key to the first box. No matter how
large the book is, this scheme can be extended to any number of
boxes by always putting the key to the next box in the previous box.
• In this analogy, the boxes correspond to elements or nodes, the keys
correspond to pointers, and the book itself is the data. The key
given to Bob is the head pointer, while those stored in the boxes are
next pointers. The scheme as described above is a singly linked list.
90. Two-way Header List
• A two-way list is a linear collection of data
elements, called nodes, where each node N is
divided into three parts :
(1). An information field INFO which contains the
data of N.
(2). A pointer field FORWARD which contains the
location of the next node in the list.
(3). A pointer field BACK which contains the
location of the preceding node in the list.
• The list is circular because the two end nodes
point back to the header node.
91.
92. Traversal
• In order Traversal
To traverse the linear linked list, we walk the list
using the pointers, and process each element until
we reach the last element.
• Reverse Order Traversal
To traverse the linear linked list in reverse order, we
walk the list until we reach the last element. The
last element is processed first, then the second last
and so on and finally the first element of the list.
93. Searching
• Searching an Element
• In a linear linked list, only linear searching is
possible. This is one of the limitations of the
linked list: we cannot directly approach any
element other than head.
• Depending on whether the list is sorted or
unsorted, a suitable searching method can be
used.
94. Underflow and Overflow
• Delete option is applied on a EMPTY list is
called Underflow
• Add option is applied on a SPACE FULL list /
NO SPACE is called Overflow
• Insertion can be performed after checking
overflow condition
• Deletion can be performed after checking
underflow condition
95.
96.
97. Insertion, Deletion, and Navigation
• Create a new Link with provided data.
• Point New Link to old First Link.
• Point First Link to this New Link.
• Get the Link pointed by First Link as Temp Link.
• Point First Link to Temp Link's Next Link.
• Get the Link pointed by First Link as Current Link.
• Check if Current Link is not null and display it.
• Point Current Link to Next Link of Current Link and
move to above step.
98. Advantages
• Linked lists are a dynamic data structure, which can
grow and be pruned, allocating and deallocating
memory while the program is running.
• Insertion and deletion node operations are easily
implemented in a linked list.
• Dynamic data structures such as stacks and queues can
be implemented using a linked list.
• There is no need to define an initial size for a linked list.
• Items can be added or removed from the middle of list.
• Backtracking is possible in two way linked list.
99. Disadvantages
• They use more memory than arrays because of the storage
used by their pointers.
• Nodes in a linked list must be read in order from the
beginning as linked lists are inherently sequential access.
• Nodes are stored incontiguously, greatly increasing the
time required to access individual elements within the list,
especially with a CPU cache.
• Difficulties arise in linked lists when it comes to reverse
traversing. For instance, singly linked lists are cumbersome
to navigate backwards and while doubly linked lists are
somewhat easier to read, memory is consumed in
allocating space for a back-pointer.
100. Doubly Linked List
• Doubly linked list is a linked data structure that
consists of a set of sequentially linked records
called nodes.
• Each node contains two fields, called links, that
are references to the previous and to the next
node in the sequence of nodes.
• The beginning and ending nodes’ previous and
next links, respectively, point to some kind of
terminator, typically a sentinel node or null, to
facilitate traversal of the list.
101. Advantages and Disadvantages
1. A DLL can be traversed in both forward and
backward direction.
2. The delete operation in DLL is more efficient,
we can get the previous node using previous
pointer
• Every node of DLL Require extra space for an
previous pointer
103. Generalized List
• A generalized linked list contains structures or
elements with every one containing its own pointer. It's
generalized if the list can have any deletions,insertions,
and similar inserted effectively into it.
struct node
{
int num;
struct node *next;
};
• node structure has a pointer representing a node
datatype.
104. Garbage Collection
• 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.
105. 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.
106. 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.