Professional Documents
Culture Documents
Algo Notes PDF
Algo Notes PDF
DATA STRUCTURE
In computer science, a data structure is a way of storing data in a computer so that
it can be used efficiently. Often a carefully chosen data structure will allow a more
efficient algorithm to be used. The choice of the data structure often begins from the
choice of an abstract data structure. A well-designed data structure allows a variety of
critical operations to be performed on using as little resources, both execution time and
memory space, as possible.
Linear data structure: Data structure is said to be linear if its elements forms a
sequence or a linearlist. Example stacks, queues, linked list….
Non linear data structure: Data structure is said to be non linear if its elements does
not form a sequence.Example tree, graphs...
Insertion: Adding new data items into a data structure is called insertion.
Deletion: Removing data items from a data structure is called deletion.
Searching: Finding specific data item ina data structure is called searhing.
Traversing: Accesing each record or item in a data srtructure exactly one for processing
is called traversing. It is also called visiting.
Sorting: Arranging data items in a data structure into a specific order is called sorting.
Merging: Combining two lists of data items into a single list is called merging.
ALGORITHM
An algorithm is a well-defined list of steps for solving a particular problem. The
time and space it uses are two major measures of the efficiency of an algorithm.
ANALYSIS OF ALGORITHM
The analysis of algorithms is a major task in computer science. In order to
compare algorithms, we must have some criteria to measure the efficiency of our
algorithms. Suppose M is an algorithm and suppose n is the size of the input data. The
time and space used by the algorithm M are the two measures for the efficiency of M.
The time is measured by counting the number of key operations – in sorting and
searching algorithms, for example, the number of comparisons. The space is measured by
counting the maximum of memory needed by the algorithm.
COMPLEXITY OF ALGORITHM
The complexity of an algorithm is the function f(n) which gives the running time
and/or space in terms of the input size n. Frequently, the storage space required by an
algorithm is simply a multiple of the data size n. The following example illustrates tat the
function f(n) which gives the running time of an algorithm, depends not only on the size
n of the input data but also on the particular data.
Example: Suppose we are given an English short story, and suppose we want to search
through TEXT for the first occurrence of the given 3- letter word W. If W is the 3-letter
word “the” then is likely that w occurs near the beginning of TEXT so f(n) will be small.
On the other hand, if W is the 3-letter word “zoo” then W may not appear in TEXT at all
so f(n) will be large.
SORTING
Sorting means arranging a set of data in some specific order. There are different
methods that are used to sort the data in ascending or descending order. These methods
can be divided into two categories.
Why do we sorting?
Searching for an element in an array will be more efficient. (Example: Looking for
an information like phone number)
It’s always nice to see data in sorted display. (Example: Spreadsheet or Database
application)
Computers sort things much faster.
Examples of Sorting:
List containing exam scores sorted from Lowest to Highest or from Highest to
Lowest.
List containing words that were misspelled and be listed in alphabetical order.
List of student records and sorted by student number or alphabetically by first or last
name.
TYPES OF SORTING:
There are two types of sorting.
1. INTERNAL SORTING
If all the data that is to be sorted can be accommodated at a time in memory then
internal sorting methods are used.
2. EXTERNAL SORTING
When the data to be sorted is so large that some of the data is present in the
memory and some is kept in auxiliary memory (hard disk, floppy, tape etc), then external
sorting methods are used
EXTERNAL SORTING
This sorting is applied to the huge amount of data that can not be accommodated
in the memory all at a time. So the data from the disk is loaded into memory part by part
and each part that is loaded is sorted and the sorted data is stored into some immediate
file. Finally all the sorted parts present in different files are merged into one single file.
Initially the original file (file number 1) is partitioned into two files (file number 2
and 3). Then one item is read from each file and the two items are written in
sorted order in a new file (file number 4).
Once again the item is read from each partitioned files (file number 2 and 3) and
these two records are written in sorted order in another new file (file number 5).
Thus alternate pair of sorted items are stored in the file number 4 and 5.
This procedure is repeated till the partitioned files (file number 2 and 3) come to
an end.
Now the following procedure is repeated twice.
Read one item from file number 4 and 5 and write them in sorted order in file
number 2.
Read one item from file number 4 and 5 and write them in sorted order in file
number 3.
Note that instead of creating two new files, the partitioned files (2 and 3) are being
reused.
After this the following procedure is repeated 4 times:
Read one item from file number 2 and 3 and write them in sorted order in file
number 4.
Read one item from file number 2 and 3 and write them in sorted order in file
number 5
In this way alternately items are moved from a pair of partitioned files to the pair
of new files and from pair of new files to a pair of partitioned files. This
procedure is repeated till the time we do not end up writing entire data in a single
file. When this happens all the items in this file would be in sorted order.
PRACTICAL EXAMPLE
How it Works?
Suppose the user enters 56, 78, 33, 81 and 12 in the array. The above example sorts these
values as follows:
PASS 1 56 78 33 81 12
56 78 33 81 12
33 78 56 81 12
33 78 56 81 12
12 78 56 81 33
PASS 2 12 78 56 81 33
12 56 78 81 33
12 56 78 81 33
12 33 78 81 56
PASS 3 12 33 78 81 56
12 33 78 81 56
12 33 56 81 78
PASS 4 12 33 56 81 78
12 33 56 78 81
ALGORITHM
Here DATA is an array with N elements. This algorithm sorts the elements in DATA.
1) Repeat Steps 2 and 3 for K=1 to N-1.
2) Set S=K+1
3) Repeat while S <= N: (Executes pass)
a. If DATA [K] > DATA[S] then
Interchange DATA[K] and DATA[S]
[End of If Structure]
b. Set S = S + 1.
[End of Inner Loop]
[End of Step 1 Outer Loop]
4) Exit.
COMPLEXITY
2. BUBBLE SORT
PRACTICAL EXAMPLE
How it Works?
Suppose the user enters 56, 78, 33, 81 and 12 in the array. The above example sorts these
values as follows:
PASS 1 56 78 33 81 12
56 78 33 81 12
56 33 78 81 12
56 33 78 81 12
56 33 78 12 81
PASS 2
56 33 78 12 81
33 56 78 12 81
33 56 78 12 81
33 56 12 78 81
PASS 3
33 56 12 78 81
33 56 12 78 81
33 12 56 78 81
PASS 4
33 12 56 78 81
12 33 56 78 81
ALGORITHM
Here DATA is an array with N elements. This algorithm sorts the elements in DATA.
1. Repeat Steps 2 and 3 for K=1 to N-1.
2. Set S=1
3. Repeat while S <= N-K: (Executes pass)
a. If DATA [S] > DATA[S+1] then
Interchange DATA[S] and DATA[S+1]
[End of If Structure]
b. Set S = S + 1.
[End of Inner Loop]
[End of Step 1 Outer Loop]
4. Exit.
COMPLEXITY
3.INSERTION SORT
PASS 1
56 78 33 42 12
56 78 33 42 12
PASS 2
56 78 33 42 12
56 33 78 42 12
33 56 78 42 12
PASS 3
33 56 78 42 12
33 56 42 78 12
33 42 56 78 12
33 42 56 78 12
PASS 4
33 42 56 78 12
33 42 56 12 78
33 42 12 56 78
33 12 42 56 78
12 33 42 56 78
ALGORITHM
COMPLEXITY
4.MERGE SORT
Suppose A is a sorted list with r elements and B is a sorted list with s elements.
The operation that combine the elements of A and B into a single sorted list C with
n = r + s elements is called merging. One simple way to merge is to place the elements of
B after the elements of A and then use some sorting algorithm on the entire list. This
method does not take advantage of the fact that A and B are individually sorted. A much
more effective algorithm is given below.
Suppose one is given two sorted decks of cards. At each step the two front cards
are compared and the smaller one is placed in the combined deck. When one of the decks
is empty, all of the remaining cards in the other deck are put at the end of the combined
deck.
22 44 55 77 88 33 66 70
22
22 44 55 77 88 33 66 70
22 33
22 44 55 77 88 33 66 70
22 33 44
22 44 55 77 88 33 66 70
22 33 44 55
22 44 55 77 88 33 66 70
22 33 44 55 66
22 44 55 77 88 33 66 70
22 33 44 55 66 70
22 44 55 77 88 33 66 70
22 33 44 55 66 70 77
22 44 55 77 88 33 66 70
22 33 44 55 66 70 77 88
Written By: KASHIF HAMEED
11
First of all we must always keep track of the locations of the smallest element of
A and the smallest element of B which have not yet been placed in C. Let NA and NB
denote these locations respectively. Also let P donate the location in C to be filled. Thus
initially we set NA = 1, NB = 1 and P = 1. At each step of algorithm we compare
A [NA] and B [NB]
And assign the smallest element to C [P]. Then we increment P by setting P = P +1 and
we either increment NA by setting NA = NA +1 or increment NB by setting NB = NB
+1, according to whether the new element in C has come from A or from B. Furthermore,
if NA > r, then the remaining elements of B are assigned to C, or if NB > s, then the
remaining elements of A are assigned to C.
ALGORITHM
MERGING (A,R,B,S,C)
Let A and B be sorted arrays with R and S elements, respectively. This algorithm
merges A and B into an array C with N = R + S elements.
[End of if structure]
3. [Assign remaining elements to C]
If NA > R, then
Repeat for K = 0,1,2,3,4……S – NB.
Set C[P + K] = B[NB + K]
[End of loop]
Else
Repeat for K = 0,1,2,3,4……R – NA.
Set C[P + K] = A[NA + K]
[End of loop]
[End of if structure]
4. Exit.
5. QUICK SORT
Quick sort is an algorithm of divide and conquer type. That is, the problem of sorting a
set is reduced to the problem of sorting two smaller sets. We illustrate this “Reduction
step” by means of a specific example.
Suppose A is a following list of 12 numbers
44 33 11 55 77 90 40 60 99 22 88 66
The reduction step of the quick sort algorithm finds the final position of one of the
numbers; in this illustration, we use the first number 44. This is accomplished as follows.
Beginning with the last number 66, scan the list from right to left, comparing each
number with 44 and stopping at the first number less than 44. The number is 22.
Interchange 44 and 22 to obtain the list.
22 33 11 55 77 90 40 60 99 44 88 66
(Observe that the number 88 and 66 to the right of 44 are each greater than 44).
Beginning with 22, next scan the list in the opposite direction from left to right,
comparing each number with 44 and stopping at the first number greater than 44. The
number is 55. Interchange 44 and 55 to obtain the list.
22 33 11 44 70 90 40 60 99 55 88 66
(Observe that the number 22, 33 and 11 to the left of 44 are each less than 44). Beginning
with 55, now scan the list in the original direction from right to left, comparing each
number with 44 and stopping at the first number less than 44. The number is 40.
Interchange 44 and 40 to obtain the list.
22 33 11 40 70 90 44 60 99 55 88 66
(Observe that the numbers to the right of 44 are greater than 44). Beginning with 40, next
scan the list in the opposite direction from left to right, comparing each number with 44
and stopping at the first number greater than 44. The number is 77. Interchange 44 and 77
to obtain the list.
22 33 11 40 44 90 70 60 99 55 88 66
(Observe that the numbers to the left of 44 are each less than 44). Beginning with 77,
now scan this list from right to left, until meeting the first number less than 44. We don’t
meet such a number before meeting 44. This means all numbers have been scanned and
compared with 44. Furthermore all numbers less than 44 now from the sub list of
numbers to the left of 44, and all numbers greater than 44 now from the sub list of
numbers to the right of 44, as shown below.
22 33 11 40 44 90 70 60 99 55 88 66
22 33 11 40 44 90 70 60 99 55 88 66
22 33 11 40 90 70 60 99 55 88 66
11 33 22 40 66 70 60 99 55 88 90
11 22 33 40 66 70 60 90 55 88 99
66 70 60 88 55 90 99
11 66 70 60 88 55 90 99
33 40 66 70 60 88 55 99
33 55 70 60 88 66
40 55 66 60 80 70
55 60 66 80 70
55 60 66 80 70
55 60 80 70
55 70 80
60 80
70
11 22 33 40 44 55 60 66 70 80 90 99
COMPLEXITY
Algorithm Worst Case Average Case Best Case
Quick Sort O(n2) Log2n Log2n
6. SHELL SORT
Shell sort is named after its inventor, Donald Shell, who published it in 1959.
It is a generalization of insertion sort, with two observations in mind.
• Insertion sort is efficient if the input is “almost sorted”.
• Insertion sort is inefficient, on average, because it moves values just one position
at a time.
Shell sort improves insertion sort by comparing elements separated by a gap of several
positions. This lets an element take “bigger steps” towards its expected position. Multiple
passes over the data are taken with smaller and smaller gap sizes. The last step of a Shell
sort is a plain insertion sort, but by then, the array of data is guaranteed to be almost
sorted.
Increment 4:
Divide the array into 4 sub arrays
18 38
32 33
12 16
5 2
18 32 12 2 38 33 16 5
Increment 2:
Divide the array into 2 sub arrays
18 12 38 16
32 2 33 5
After arranging the sub arrays
12 16 18 38
2 5 32 33
The complete array will be
12 2 16 5 18 32 38 33
floor (2/2) → floor (1) = 1
Increment 1:
Now sort the array by insertion sort and resulting array will be
2 5 12 16 18 32 33 38
ARRAY SEARCHING TECHNIQUES
1.LINEAR SEARCH
Suppose a linear array DATA contains n elements and suppose a specific ITEM
of information is given. We want either to find the location LOC of ITEM in the array
DATA or to send some message, such as LOC = 0, to indicate that ITEM does not appear
in DATA. The linear search algorithm solves this problem by comparing ITEM, one by
one, with each element in DATA. That is we compare ITEM with DATA [1], then
DATA [2] and so on, until we find LOC such that ITEM = DATA [LOC].
ALGORITHM
(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 sets LOC = 0.
2. BINARY SEARECH
DATA[BEG],DATA[BEG+1],DATA[BEG+2],………………..DATA[END]
Note that the variables BEG and END denote, respectively, the beginning and end
locations of the segment under consideration. The algorithm compares ITEM with the
middle element DATA [MID] of the segment, where MID is obtained by
Initially we begin with the entire array DATA i.e we begin with BEG = 1 and END = n
more generally with BEG=LB and END = UB.
If ITEM is not in the DATA then eventually we obtain
END < BEG
This condition signals that the search is unsuccessful and in such a case we assign LOC =
NULL. Here NULL is a value that lies outside the set of indices of DATA.
ALGORITHM
(Binary search) BINARY (DATA, LB, UB, ITEM, LOC)
Here DATA is 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 locations of a segment of elements of DATA. This algorithm
finds the location LOC of ITEM in DATA or sets LOC = NULL.
DATA: 11 22 30 33 40 44 55 60 66 77 80 88 99
We apply the binary search to DATA for different values of ITEM.
1. Suppose ITEM = 40. The search for ITEM in the array DATA is shown below where
the values of DATA [BEG] and DATA [END] in each stage are indicated by circles
and the value of DATA [MID] by a square.
a) Initially BEG =1 and END = 13. Hence
MID = INT ((1+13) /2) = 7 and so DATA [MID] = 55
11 22 30 33 40 44 55 60 66 77 80 88 99
b) Since 40 < 55, END has its value changed by END = MID –1 = 6, BEG = 1
Hence MID = INT ((1+6) / 2) = 3 and so DATA [MID] = 30
11 22 30 33 40 44 55 60 66 77 80 88 99
c) Since 40 > 30, BEG has its value changed by BEG = MID +1 = 4, END = 6
Hence MID = INT ((4+6) / 2) = 5 and so DATA [MID] = 40
11 22 30 33 40 44 55 60 66 77 80 88 99
We have found ITEM in location LOC = MID = 5 [Successful]
2. Suppose ITEM = 85. The search for ITEM in the array DATA is shown below
a) Initially BEG =1 and END = 13,
MID = INT ((1+13) /2) = 7 and so DATA [MID] = 55
11 22 30 33 40 44 55 60 66 77 80 88 99
b) Since 85 > 55, BEG has its value changed by BEG = MID +1 = 8, END = 13
Hence MID = INT ((8+13) / 2) = 10 and so DATA [MID] = 77
11 22 30 33 40 44 55 60 66 77 80 88 99
c) Since 85 > 77, BEG has its value changed by BEG = MID +1 = 11, END = 13
Hence MID = INT ((11+13) / 2) = 12 and so DATA [MID] = 88
11 22 30 33 40 44 55 60 66 77 80 88 99
d) Since 85 < 88, END has its value changed by END = MID –1 = 11, BEG = 11
Hence MID = INT ((11+11) / 2) = 11 and so DATA [MID] = 80
(Observe that now BEG = END = MID = 11.)
11 22 30 33 40 44 55 60 66 77 80 88 99
Since 85 > 80, BEG has its value changed by BEG = MID +1 = 12. END = 11
But now BEG > END. Hence ITEM does not belong to DATA.
[Unsuccessful]
LINKED LISTS
Why Linked Lists are preferred over arrays?
For storing similar data in memory, we can use either an array or a linked list.
Arrays are simple to understand and elements of an array are accessible but arrays suffer
from the following limitations.
• Arrays have a fixed dimension. Once the size of an array is decided it can not be
increased or decreased during execution.
• Arrays elements are always stored in contiguous memory locations. At time it
might so happen that enough contiguous location might not be available for the
array that we are trying to create.
• Operation like insertion of a new element or deletion of existing element from the
array is pretty tedious. This is because during insertion or deletion each element
has to be shifted one position to the right or to the left.
Linked list overcome all these limitations.
• A linked list can grow and shrink in size during its life time that is there is no
maximum size of linked list.
• As nodes of linked list are stored at different memory locations it hardly happened
that we fall short of memory when required.
• Unlike arrays while inserting or deleting the nodes of the linked list, shifting of
nodes is not required.
SINGLE/ONE WAY/LINEAR LINKED LIST
It is the very common data structure often used to store similar data in memory.
Elements of the linked list are called nodes. Each node consists of a data part and a link
part. A link is a pointer or an address that indicates the location of the node containing the
successor of the list element. N stands for NULL which indicates that this is the last node
in the list.
BUILDING A LINKED LIST
• Allocate the memory for the first node.
200
• Set a value in the data part and NULL in the link part.
70 N
200
• Allocate the memory for the second node.
100
• Set a value in the data part and NULL in the link part.
50 N
100
• Set the link part of the first node with the address of the second.
70 100 50 N
200 100
The variable “p” has been declared as pointer to a node. We have used this pointer
as pointer to the 1st node in the linked list.
How many nodes get added to the linked list? P would continue to point t the 1st
node in the list. When no node has added to the list, p has been set to NULL to indicate
that the list is empty.
Addition of a node in a linked list
• To an empty list.
• At the end.
• At the beginning.
• In the middle (anywhere)
Append function
This function deals with two situations:
• The node is being added to an empty list.
• The node is being added at the end of the existing list.
In the 1st case the condition
if(p = = NULL) gets satisfied then space is allocated for the node using new operator.
temp = new node;
Data and link part of this node are setup using the statements.
temp→data = num;
temp→link = NULL;
In the 2nd case when the linked list is not empty, the condition
if(p = = NULL) would fail.Now temp is made to point to the first node in the list.
temp=p;
Then using temp we have traversed through the entire linked list using a statement
while(temp→link !=NULL)
temp= temp→link;
Every time through the loop the statement
temp= temp→link;
makes temp point to the next node in the list. When temp reaches the last node, the
condition
temp→link !=NULL
would fail.
Allocate the memory for the new node and set pointer “r” to point this node.
r = new node;
Set a value in the data part and NULL in the link part of the new node. All that now
remains to be done is connecting the previous last node to the new last node. This is done
through statement.
temp→link = r;
p temp
70 200 50 400 10 N
Append function
p=NULL;
append(int num)
{
node *temp, *r;
if(p = = NULL)
{
temp = new node;
temp→data = num;
temp→link = NULL;
}
else
{
temp=p;
while(temp→link !=NULL)
temp= temp→link;
r = new node;
r→data = num;
r→link = NULL;
temp→link = r;
}
}
Lastly this new node must be made the 1st node in the list. This is done by the statement.
p = temp;
temp p
To begin with, “temp” is set to point the 1st node through statement
temp = p;
Then through loop, we skip number of nodes after which a new node is to be added.
Suppose we wish to add a new node after the 3rd node in the list. Allocate memory for the
new node and set pointer “r” to point this node.
r = new node;
Using “r” set a value in the data part of the node. All that remains to be done is
readjustment of links such that the new node adjusts in between the 3rd and 4th node and
this is achieved through the statement. r
r→link = temp→link;
temp→link = r; 50 N
p temp 300
70 200 50 400 10 N
100 200 400
50 400
p temp
300
70 200 50 300 10 N
100 200 400
P old temp
p old
70 200 50 300 40 N
while(temp!=NULL)
{
if(temp→data = num)
{
if(temp= p)
p = temp→link;
else
old→link = temp→link;
delete temp;
return;
}
else
{
old = temp;
temp = temp→link;
}
}
printf(“Element not found”);
}
Display function
display()
{
node *temp = p;
while(temp != NULL)
{
printf(“%d”, temp→data);
temp = temp→link;
}
}
Count function
count()
{
node *temp = p;
int c = 0;
while(temp != NULL)
{
temp = temp→link;
c ++;
}
return c;
}
ASCENDING ORDER LINKED LIST
Let us now try to understand the function “add” that is responsible for maintaining the
linked list in the ascending order.
The pointer “p” either holds the address of the 1st node or a NULL value in case of empty
linked list. The add() function takes one parameter num that holds the data that is to be
inserted in the list.
Initially memory is allocated for the new node, its address is stored in pointer ”r” and
using “r” the value of num is stored in its data part.
There are four different places where the new node can be added in the list
a) To an empty list.
b) At the beginning.
c) At the end.
d) In the middle (anywhere)
CASE “C”
p temp
50 200 70 400 80 N
100 200 400
p temp r
CASE “D” r
70 N
p temp 300
40 200 50 400 90 N
r
70 400
p temp 300
40 200 50 300 90 N
During the 2nd iteration of the while loop, “r” points to the 1st node and “q” points to the
2nd node.Now the link part of the 2nd node should point to the 1st node which is done
through the same statement.
s = r; r = q; q = q→link;
After the statement “s” would point to the 1st node and “r” would point to the 2nd node
and r→link starts pointing to the 1st node. But if we store the value of “s” in the link part
of the 2nd node, address of the 3rd node would be lost. So before this step “q” is made to
point to the third node. q = q→link;
While traversing through while loop, each time “q” starts pointing to the next node and
“r” starts pointing to the previous node.
As a result, when the while loop ends, all the links have been adjusted properly.
Finally outside the while loop, the statement p = r;
ensures that the pointer “p” now start pointing to the node which is the last node of the
original list.
p q r = NULL
2 N 8 400 4 300 3 N
p s r q
2 N 8 100 4 300 3 N
100 200 400 300
p s r q
2 N 8 100 4 200 3 N
q = NULL
p s r
r p
b) Keep the data in the nodes intact. Simply readjust the links such that effectively the
order of the nodes changes.
Of the two methods, first one is easier to implement, but the second one is likely to be
more efficient. This is because if the data part contains an employee record (containing
name, age, salary etc) then to carry out exchange of this record would be inefficient time
wise as well as space wise. Instead if we adopt second method, since we are only
readjusting the links this would involve only pointers and not trhe bulky structures
representing records.
r = r→link;
}
q = q→link;
}
}
r = r→link;
q = q→link;
}
}
}
Although a linear linked list is a useful data structure, it has several short comings. For
example, given a pointer p to a node in a linear list, we can not reach any of the nodes
that precede the node to which p is pointing. This disadvantage can be overcome by
circular linked list.
From any point in such a list it is possible to reach any other point in the list. If we begin
at a given node and traverse the entire list, we ultimately end up at the starting point. A
circular linked list does not have a first or last node. We must, therefore, establish a first
and last node by convention. A circular linked list can be used to represent a stack and a
queue.
Addition in the circular linked list
{
node *q;
int num;
if(front = NULL)
printf(“Queue is empty”);
else
{
if(front = rear)
{
num = front→data;
delete front;
front = NULL;
rear = NULL;
}
else
{
q = front;
num = q→data;
front = front→link;
rear→link = front;
delete q;
}
}
Front Rear
Front Rear
Display function
cirq_display()
{
node *q, *p;
q = front;
p = front;
do
{
printf(“%d”, q→data);
q = q→link;
}
while(q != p)
}
The linked list in which each node stores not only the address of next node but
also the address of previous node is called double linked list or two way linked list.
struct dnode
{
dnode *prev;
int data;
dnode *next;
} *p;
Append function
d_append (int num)
{ dnode *q, *r;
if(q = = NULL)
{ q = new dnode;
q→data = num;
q→prev = NULL;
q→next = NULL;
p = q;
}
else
{ while(q→next !=NULL)
q = q→next;
r = new dnode;
r→data = num;
r→next = NULL;
r→prev = q;
q→next = r;
}
}
Add a node at the beginning
Add_at_beg(int num)
{
dnode *q;
q = new dnode;
q→prev = NULL;
q→next = p;
q→data = num;
p→prev = q;
p = q;
}
Adding a node after specific node in double linked list
Add_after(int loc, int num)
{
dnode *q, *r;
q = p;
for(int i = 0; i<loc ; i++)
{ q = q→next;
if(q = NULL)
{ printf(“There are less nodes in the list”);
return;
}q = q→prev;
r = new dnode;
r→data = num;
r→prev = q;
r→next = q→next;
r→next→prev = r;
q→next = r;
}
temp
p q 300
N 90 N
{
dnode *q = p;
while(q!=NULL)
{
if(q→data = num)
{
if(q = = p)
{
p = p→next;
p→prev = NULL;
}
else
{
if(q→next = NULL)
q→prev→next = NULL;
else
{
q→prev→next = q→next;
q→next→prev = q→prev;
}
delete q;
}
return;
}
q = q→next;
printf(“Element not found”);
}
STACK
A stack is a data structure in which addition of new element or deletion of an
existing element always takes place at the same end. This end is known as top of the
stack. When an item is added t the stack the operation is called “push” and when an item
is removed from the stack the operation is called “pop”. Stack is also called LIFO (Last
in First out) list. If the elements are added continuously to the stack it grows at one end.
On deletion of elements the stack shrinks at the same end, as the elements at the top get
removed.
For example stack of plates in cafeteria where every new plate added to the stack
is added at the top. Similarly, every new plate taken off the stack is also from the top of
the stack.
top top
top 5 5 top
top 4 4 4 4 top
top
1 1 1 1 1 1 top
top= NULL 3 3 3 3 3 3 3 3 top = NULL
2 2 2 2 2 2 2 2
Push function
void push( int item)
{
if( top == MAX-1)
{
printf(“Stack is full);
return;
}
top ++;
arr[top] = item;
}
Pop function
void pop( )
{
if( top == -1)
{
printf(“Stack is emptyl);
return;
}
int data = arr[top];
top --;
return data;
}
ALGORITHM OF PUSH FUNCTION
Push(arr, top, MAX, item)
This procedure pushes an item onto a stack
1. [Stack already filled?]
if top == MAX-1 then print overflow and return
PUSH FUNCTION
struct node
{
int data;
node *link;
} *top
void stack_push( int num)
{
node *temp;
temp = new node;
temp→data = num;
temp→link = top;
top = temp;
}
POP FUNCTION
void stack_pop( )
{
if( top == NULL)
{
printf(“Stack is emptyl);
return;
}
node *temp;
int num;
temp = top;
num = temp→data;
top = top→link;
delete temp;
return num;
}
APPLICATIONS OF STACK
The place where stacks are frequently used is in evaluation of arithmetic
expression. An arithmetic expression consists of operands and operators. The operands
can be numeric values or numeric variables. The operators used in arithmetic expression
represent the operations like addition, subtraction, multiplication, division and
exponentiation.
INFIX NOTATION
While writing an arithmetic expression, the operator symbol is usually placed
between two operands. For example
a+b
a*b+c
b–c/c
This way of representing arithmetic expressions is called infix notation. While
evaluating an infix expression usually the following operator precedence is used.
• Highest priority: Exponentiation ($)
• Next highest priority: Multiplication (*) and Division (/)
• Lowest priority: Addition (+) and Subtraction (-)
If we wish to override these priorities we can do so by using a pair of parentheses
as shown below
(a + b) *c
a * (b - c)
POLISH NOTATION
A Polish mathematician which gives two alternatives to represent an arithmetic
expression. The notations are prefix and postfix notations.
The fundamental property of Polish notation is that the order in which the operations are
to be performed is completely determined by the positions of the operators and operands
in the expression. Hence, parentheses are not required while writing expressions in Polish
notation.
PREFIX NOTATION
In prefix notation the operator comes before the operands. For example consider
an arithmetic expression expressed in infix notation as shown below:
a+b
This expression in prefix form would be represented as follows.
+ab
POSTFIX NOTATION
In postfix notation the operator comes after the operands. For example consider
an arithmetic expression expressed in infix notation as shown below:
a+b
This expression in prefix form would be represented as follows.
ab+
The prefix and postfix expressions have three features.
• The operands maintain the same order as in the equivalent infix expression.
• Parentheses are not needed to designate the expression unambiguously.
• While evaluating the expression the priority of the operators is irrelevant.
INFIX TO PREFIX CONVERSION. (RULES)
1. If the character scanned happens to be a space then the character is skipped.
2. If character scanned is a digit or an alphabet, it is added to the target string.
3. If the character scanned happens to be closing parentheses, then it is added to
stack.
4. If the character scanned happens to be an operator then firstly the top most
element from the stack is retrieved. Then, through a while loop, the priorities of
the character scanned and the character popped are compared.
a) If the priority of character popped is higher than the character
scanned, then character popped gets added to the target string.
b) If the character popped has lower or same priority than the character
scanned then the loop terminated. The character popped pushed back to
stack then the character scanned is also pushed to the stack.
5. If the character scanned happens to be opening parentheses, then the operators
entered into the stack are retrieved through a loop. The loop continues till it does
not encounter closing parentheses. The operators popped are added to the target
string.
INFIX TO POSTFIX CONVERSION. (RULES)
1. If the character scanned happens to be a space then the character is skipped.
2. If character scanned is a digit or an alphabet, it is added to the target string.
3. If the character scanned is opening parentheses, then it is added to stack.
4. If the character scanned happens to be an operator then firstly the top most
element from the stack is retrieved. Then, through a while loop, the priorities of
the character scanned and the character popped are compared.
a) If the character popped has higher or same priority than the character
scanned, then character popped gets added to the target string.
b) If the character popped has lower priority than the character scanned then
the loop terminated. The character popped pushed back to stack then the
character scanned is also pushed to the stack.
5. If the character scanned happens to be closing parentheses, then the operators
entered into the stack are retrieved through a loop. The loop continues till it does
not encounter opening parentheses. The operators popped are added to the target
string.
INFIX TO PREFIX
Infix expression: 4 $ 2 * 3 – 3 + 8 / 4 / ( 1 + 1)
Infix expression: (A - B) * ( D / E)
Infix expression: (A + B $ D) / (E - F) + G
PREFIX TO INFIX
Prefix expression: + – * $ 4 2 3 3 / / 8 4 + 1 1
Reversed Prefix expression: 1 1 + 4 8 / / 3 3 2 4 $ * – +
Prefix expression: – / * 10 + 2, 2, 4 * 4 + 2 / 3, 3
Reversed Prefix expression: 3, 3 / 2 + 4 * 4, 2, 2 + 10 * / –
INFIX TO POSTFIX
Infix expression: (A + B $ D) / (E - F) + G
Infix expression: 4 $ 2 * 3 – 3 + 8 / 4 / ( 1 + 1)
Char scanned Stack Postfix Expression
4 Empty 4
$ $ 4
2 $ 4, 2
* * 4,2, $
3 * 4,2, $, 3
– – 4, 2, $, 3, *
3 – 4, 2, $, 3, *, 3
+ + 4, 2, $, 3 * 3 –
8 + 42 $ 3 * 3– 8
/ +/ 42 $ 3 * 3– 8
4 +/ 42 $ 3 * 3–8 4
/ +/ 42 $ 3 * 3– 84 /
( +/( 42 $ 3 * 3– 84 /
1 +/( 42 $ 3 * 3– 84 / 1
+ +/(+ 42 $ 3 * 3– 84 / 1
1 +/(+ 42 $ 3 * 3– 84 / 1 1
) +/ 42 $ 3 * 3– 84 / 1 1 +
+ 42 $ 3 * 3– 84 / 1 1 + /
Empty 42 $ 3 * 3– 84 / 1 1 + / +
Infix expression: (A + B) * (C - D) $ E * F
Char scanned Stack Postfix Expression
( (
A ( A
+ (+ A
B (+ AB
) Empty AB +
* * AB +
( *( AB+
C *( AB+C
– *(– AB+C
D *(– A B + CD
) * A B + CD –
$ *$ A B + CD –
E *$ A B + CD – E
* * A B + CD – E $ *
F * A B + CD – E $ * F
Empty A B + CD – E $ * F *
Infix expression: (A – B) * ( D / E)
Char scanned Stack Postfix Expression
( (
A ( A
– (– A
B (– AB
) Empty AB –
* * AB –
( *( AB –
D *( AB – D
/ *(/ AB – D
E *(/ AB – DE
) * AB – DE /
Empty AB – DE / *
POSTFIX TO INFIX
Postfix expression: A B + CD – E $ * F *
Char scanned Stack
A A
B A B
+ A+B
C A+BC
D A+B C D
– A+B C–D
E A+B C–D E
$ A+B C–D$E
* A+B*C–D$E
F A+B*C–D$EF
* A + B * C – D $ E *F
Postfix expression: 3, 2, +, 5, 4, –, 1, $, *, 6, *
Postfix expression: 4, 2, $, 3, *, 3, –, 8, 4, /, 1, 1, +, /, +
Convert the following infix expressions into their equivalent prefix and postfix
expressions.
1. (A +B) * (C – D) $ E *F
2. A +B *C + (D * E +F) * G
3. A * (B +D)/ E – F * (G + H / K)
Answers
1. *, *, +, A, B, $, –, C, D, E, F and A B + C D – E $ * F *
2. +, +, A, B, C, *, +, *,D, E, F, G and A B C * + D E * F + G * +
3. –, / *, A + B, D, E, *, F, +, G, /, H, K and A B D + * E / F G H K / +
Convert the following prefix expressions into their equivalent infix expressions. Also
evaluate them.
1. *, *, +, A, B, $, –, C, D, E, F (where A =6, B =5, C =4, D =3, E =2, F =1)
2. +, /, +, A, $, B, D, –, E, F, G (where A =6, B =5, D =4, E =3, E =2, G =1
3. * - A B / D E (where A = 10, B = 5, D = 16, E = 4)
Answers
1. A +B * C – D $ E *F and 11
2. A + B $ D / E - F + G and 632
3. A – B * D / E and 20
Convert the following postfix expressions into their equivalent infix expressions.
Also evaluate them.
1. 3, 1, +, 2, ↑, 7, 4, –2, *, +, 5, –
2. 6, 2, 3, +, –, 3, 8, 2, /, +, *, 2, ↑, 3, +
3. A, B, +, C, –, B, A, +, C (where A = 1, B = 2, C = 3)
4. A, B, -, D, E, /, * (where A = 10, B = 5, D = 16, E = 4)
Answers
1. 3 + 1 ↑ 2+ 7 – 4 * 4 * 2 – 5 and 17
2. 6 – 2 + 3 * 3 + 8 / 2 ↑ 2 + 3 and 52
3. A + B – C – B + A ↑ C and – 9
4. A – B * D / E and 20
QUEUE
Queue is a linear data structure that permits insertion of a new element at one end
and deletion of an element at the other end. Placing an item in a queue is called
“insertion or enqueue”, which is done at the end of the queue called “rear”. Removing
an item from a queue is called “deletion or dequeue”, which is done at the other end of
the queue called “front”.
The first element tat gets added into the queue is the first one to get removing
from the list. Hence queue is also referred as FIFO (First in First Out) list.
Example:
Consider a queue of people waiting at the bus stop. Each new person who comes
takes his place at the end of the line. And when the bus comes, the people at the front of
the line board first. The first person in the line is the first person to leave.
A B C D E F
Front Rear
Applications of queue as a data structure are even more common than applications
of stacks. While performing tasks on a computer, it is often necessary to wait one’s turn
before having access to some device or process. Within a computer system, there may be
queues of tasks waiting for the linear printer, or for access to disk storage, or in a time
sharing system for the use of the CPU.
Deletion in a queue
void del_q( int item)
{
int data;
if( front == -1)
{
printf(“Queue is empty”);
return;
}
data = arr[front];
arr[front] = 0;
if(front == rear)
front = rear = -1;
else
front++;
return data;
}
Representation of a queue as a linked list
Addition in a queue
void add_q( int item)
{
node *temp;
if( temp == NULL)
{ printf(“Queue is full”);
temp→data = item;
temp→link = NULL;
if( front == NULL)
rear = front = temp;
return;
}
rear→link = temp;
rear = rear→link;
}
Deletion in a queue
void del_q()
{
int item;
node *temp;
if( front == NULL)
{
printf(“Queue is empty”);
temp = front;
item = front→data;
front = front→link;
delete temp;
}
CIRCULAR QUEUE
In a simple queue, there is a possibility that the queue is reported as full ( since
rear has reached the end of the array), even though in actually there might be empty slots
at the beginning of the queue.
To overcome this limitation, we can implement the queue as circular queue. In
circular queue as we go on adding elements to the queue and reach the end of the array,
the next element is stored in the first slot of the array ( provided it is free).
Front Rear
Queue is Empty -1 -1
FR
Insert 1 element 6 0 0
F R
Insert 2 elements 6 3 4 0 2
F R
Insert 2 elements 6 3 4 8 5 0 Full 4
F R
Delete 3 elements 8 5 3 4
R F
Insert 3 elements 3 2 1 8 5 3 Full 2
F R
Delete 3 elements 2 1 1 2
FR
Delete 1 element 1 2 2
Queue is Empty -1 -1
else
{
if(front == MAX -1)
front = 0;
else
front++;
}
return data;
}
DEQUE
It is pronounced as “dequeue” or “deck”. It is short form of double ended queue
and defined as the data structure in which items can be added or deleted at either the front
or rear end but no changes can be made elsewhere in the list. Thus deque is
generalization of both stack and queue.
Insertion
Deletion
A B C D E F
Deletion Insertion
Front Rear
VARIATION OF DEQUE
There are two variations of deque.
1. Input Restricted Deque.
An input restricted deque restricted the insertion of element at one end only but
the deletion of an element can be done at both ends of the deque.
Deletion
Deletion A B C D E F
Insertion
Front Rear
Deletion
Insertion A B C D E F
Insertion
Front Rear
PRIORITY QUEUES
Priority queue is the collection of elements where the elements are stored
according to their priority level. The order in which the element should get added or
remove is decided by the priority of an element.
Rules:
Following Rules Are Applied To Maintain A Priority Queue.
• The element with the higher priority is processed before any element of low
priority.
• If there are elements with the same priorities, then the element added first in the
queue would get processed first.
Priority queues are used for implementing job scheduling by the operating system where
obs with higher priorities are to be processed first. Another application of priority queues
is simulation systems where priority corresponds to event time.
#include<stdio.h>
#include<conio.h>
void pushstack(int);
void popstack();
void printstack();
void pushqueue(int);
void popqueue();
void reversestack();
int front, rear, top, n, i, temp, stack[10], queue[10];
void main()
{
clrscr();
front = top = rear = -1;
printf("Enter the number of elements to be added in stack==");
scanf("%d", &n);
if(n>10)
printf("The number should be between 1 and 10");
else
{
for(i=0; i<noe; i++) {
printf("Enter the element==");
scanf("%d", &temp);
pushstack(temp); }
printstack();
reversestack();
}
getch();
}
/*-------------------------------------------------------------------------------*/
12 3 32 2
34 8 7 4
82 81 5 6
int a[3][4] = {
{12,3,32,2},
{34,8,7,4},
{82,81,5,6},
};
12 3 32 2 34 8 7 4 82 81 5 6
502 504 506 508 510 512 514 516 518 520 522 524
12 34 82 3 8 81 32 7 5 2 4 6
502 504 506 508 510 512 514 516 518 520 522 524
In Row Major Order, in general for an array a[m][n] the address of element a[i][j] would
be base address + i * n + j
e.g element 4 is present at a[1][3]. Hence location of 4 would be
= 502 + 1 * 4 + 3
= 502 + 7 (i.e 7 * 2 =14)
= 516
In Column Major Order, in general for an array a[m][n] the address of element a[i][j]
would be base address + j * m + i
e.g element 4 is present at a[1][3]. Hence location of 4 would be
= 502 + 3 * 3 + 1
= 502 + 10 (i.e 10 * 2 =20)
= 522
ALGORITHMS
Inserting a value at specified location in an array.
This algorithm insert a value M at location loc in array A having N elements.
1) Input value in M.
2) Input position in loc
[Move elements one step forward]
3) Repeat step 4 to 5 while N > = loc
4) A [N+1] = A [N]
5) N =N -1
[End of step 3 loop]
6) [Insert value M at position loc]
A[loc] = M
7) Exit
Deleting an item from an array at specified location
This algorithm deletes a value at location K in array A having N elements.
1) Input location K
2) if K > N then
Print “Invalid location”
Return
End If
[Move each element from the specified location one step towards the beginning. The
item at the specified location is automatically deleted]
3) Repeat for C = K to N-1
A[C] = A[C+1]
[End of loop]
4) Exit
Search a sub string in a string
This algorithm search a substring “sub” in a string “str”
1) Input string in str.
2) Input substring in sub.
3) Find length of str in len.
4) Find length of sub in sublen.
5) Compute total sub strings in str.
6) T = len – sublen + 1
7) C = 0
8) Repeat step 9 to 10 while C <= T
9) Repeat step 10 for X = 0 to sublen
10) If X = sublen then
Print “sub string found at position =”, C +1
Exit
End If
If sub[X] != str[C + X] then
C=C+1
Go to step 8
End If
[End of step 9 inner loop]
[End of step 8 outer loop]
11) Print “ sub String not found”
12) Exit