Data Structures and Algorithms
Data Structures and Algorithms
1. AN ARRAY
An ARRAY is a data structure, which can store a fixed-size collection of elements of the same
data 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.
Instead of declaring individual variables, such as number1, number2, ... number99, you just
declare one array variable number of integer type and use number1[0], number1[1], and ...,
number1[99] to represent individual variables. Here, 0, 1, 2, .....99 are index associated
with var variable and they are being used to represent individual elements available in the array.
All arrays consist of contiguous memory locations. The lowest address corresponds to the first
element and the highest address to the last element.
Create Arrays
To create an array variable in C, a programmer specifies the type of the elements and the
number of elements to be stored in that array. Given below is a simple syntax to create an array
in C programming −
type arrayName [ arraySize ];
This is called a single-dimensional array. The arraySize must be an integer constant greater
than zero and type can be any valid C data type. For example, now to declare a 10-element
array called number of type int, use this statement −
int number[10];
Here, number is a variable array, which is sufficient to hold up to 10 integer numbers.
Initializing Arrays
You can initialize an array in C either one by one or using a single statement as follows −
int number[5] = {10, 20, 30, 40, 50};
The number of values between braces { } cannot be larger than the number of elements that we
declare for the array between square brackets [ ].
If you omit the size of the array, an array just big enough to hold the initialization is created.
Therefore, if you write −
int number[] = {10, 20, 30, 40, 50};
You will create exactly the same array as you did in the previous example. Following is an
example to assign a single element of the array −
number[4] = 50;
The above statement assigns element number 5th in the array with a value of 50. All arrays have
0 as the index of their first element which is also called the base index and the last index of an
array will be the total size of the array minus 1. The following image shows the pictorial
representation of the array we discussed above −
An element is accessed by indexing the array name. This is done by placing the index of the
element within square brackets after the name of the array. For example −
int var = number[9];
The above statement will take the 10th element from the array and assign the value
to var variable. The following example uses all the above-mentioned three concepts viz.
creation, assignment, and accessing arrays
Arrays in Java
Following is the equivalent program written in Java. Java supports arrays, but there is a little
difference in the way they are created in Java using the new operator.
You can try to execute the following program to see the output, which must be identical to the
result generated by the above C example.
while( i < 10 ) {
number[ i ] = i + 100;
i = i + 1;
}
i = 0;
while( i < 10 ) {
System.out.format( "number[%d] = %d\n", i, number[i] );
i = i + 1;
}
}
}
When the above program is executed, it produces the following result −
number[0] = 100
number[1] = 101
number[2] = 102
number[3] = 103
number[4] = 104
number[5] = 105
number[6] = 106
number[7] = 107
number[8] = 108
2. A QUEUE
Queue is ordered collection of homogeneous data elements in which insertion and deletion
operation take place at two end . insertion allowed from starting of queue called FRONT point
and deletion allowed from REAR end only
CONDITIONS IN QUEUE
FRONT < 0 ( Queue is Empty )
REAR = Size of Queue ( Queue is Full )
FRONT < REAR ( Queue contains at least one element )
No of elements in queue is : ( REAR - FRONT ) + 1
RESTRICTIONS IN QUEUE
we can not insert element directly at middle index (position) in Queue and vice verse for
deletion. insertion operation possible at REAR end only and deletion operation at FRONT end,
to insert we increment REAR and to delete we increment FRONT.
Steps:
1. If ( FRONT = 0 ) then
2. print "Queue is empty"
3. Exit
4. Else
5. ITEM = Que [ FRONT ]
6. If ( FRONT = REAR )
7. REAR = 0
8. FRONT = 0
9. Else
10. FRONT = FRONT + 1
11. End if
12. End if
13. Stop
OR
Deletion in a queue
APPLICATION of QUEUE
In general, queues are often used as "waiting lines". Here are a few examples of where queues
would be used:
In operating systems, for controlling access to shared system resources such as printers,
files, communication lines, disks and tapes.
o In the situation where there are multiple users or a networked computer system,
you probably share a printer with other users. When you request to print a file,
your request is added to the print queue. When your request reaches the front of
the print queue, your file is printed. This ensures that only one person at a time
has access to the printer and that this access is given on a first-come, first-served
basis.
For simulation of real-world situations. For instance, a new bank may want to know how
many tellers to install. The goal is to service each customer within a "reasonable" wait
time, but not have too many tellers for the number of customers. To find out a good
number of tellers, they can run a computer simulation of typical customer transactions
using queues to represent the waiting customers.
When placed on hold for telephone operators. For example, when you phone the toll-free
number for your bank, you may get a recording that says, "Thank you for calling A-1
Bank. Your call will be answered by the next available operator. Please wait." This is a
queuing system.
Example: A pile of plates in a cafeteria can be a good example of a stack. The plates get added
to the stack as they get cleaned and also whenever a late is required it is taken from the top of the
stack. The first plate placed on the stack is the last one to be used.
Mainly the following three basic operations are performed in the stack:
1. Push: Push operation adds an item/data in to the stack. If the stack is full, then it is called
an Overflow condition.
2. Pop: Pop operation removes an item/data from the stack. The items are popped in the
reversed order in which they are pushed into the stack. If the stack is empty, then it is
called an Underflow condition.
3. isEmpty: Returns true if stack is empty, else false.
Applications of stack:
Balancing of symbols
Infix to Postfix /Prefix conversion
Implementing function calls (recursion)
Undo sequence in a text editor
Forward and backward feature in web browsers
Other applications can be Backtracking, Knight tour problem, rat in a maze, N queen
problem and sudoku solver
1. Using array
2. Using linked list
Deletion in stack
These two procedures are so simple that they perhaps need no more explanation. Procedure
delete actually combines the functions TOP and DELETE, stack full and stack empty are
procedures which are left unspecified since they will depend upon the particular application.
Often a stack full condition will signal that more storage needs to be allocated and the program
re-run. Stack empty is often a meaningful condition.
Java
/* Java program to implement basic stack operations */
class Stack
{
static final int MAX = 1000;
int top;
int a[] = new int[MAX]; // Maximum size of Stack
boolean isEmpty()
{
return (top < 0);
}
Stack()
{
top = -1;
}
boolean push(int x)
{
if (top >= MAX)
{
System.out.println("Stack Overflow");
return false;
}
else
{
a[++top] = x;
return true;
}
}
int pop()
{
if (top < 0)
{
System.out.println("Stack Underflow");
return 0;
}
else
{
int x = a[top--];
return x;
}
}
}
// Driver code
class Main
{
public static void main(String args[])
{
Stack s = new Stack();
s.push(10);
s.push(20);
s.push(30);
System.out.println(s.pop() + " Popped from stack");
}
}
NOTATIONS
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
Infix notation needs extra information to make the order of evaluation of the operators clear:
rules built into the language about operator precedence and associativity, and brackets () to allow
users to override these rules. For example, the usual rules for associativity say that we perform
operations from left to right, so the multiplication by A is assumed to come before the division
by D. Similarly, the usual rules for precedence say that we perform multiplication and division
before we perform addition and subtraction.
Although 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. In the example above, although the division is the first operator on the left, it acts
on the result of the multiplication, and so the multiplication has to happen before the division
(and similarly the addition has to happen before the multiplication).
Because Postfix operators use values to their left, any values involving computations will already
have been calculated as we go left-to-right, and so the order of evaluation of the operators is not
disrupted in the same way as in Prefix expressions.
Operators are written after their operands. The infix expression given above is equivalent
to A B C + * D /
The order of evaluation of operators is always left-to-right, and brackets cannot be used to
change this order. Because the "+" is to the left of the "*" in the example above, the addition
must be performed before the multiplication.
Operators act on values immediately to the left of them. For example, the "+" above uses the "B"
and "C". We can add (totally unnecessary) brackets to make this explicit:
( (A (B C +) *) D /)
Thus, the "*" uses the two values immediately preceding: "A", and the result of the addition.
Similarly, the "/" uses the result of the multiplication and the "D".
EXAMPLES
CONVERTION BETWEEN THESE NOTATIONS
The most straightforward method is to start by inserting all the implicit brackets that show the
order of evaluation e.g.:
You can convert directly between these bracketed forms simply by moving the operator within
the brackets e.g. (X + Y) or (X Y +) or (+ X Y). Repeat this for all the operators in an
expression, and finally remove any superfluous brackets.
You can use a similar trick to convert to and from parse trees - each bracketed triplet of an
operator and its two operands (or sub-expressions) corresponds to a node of the tree. The
corresponding parse trees are:
4. LINKED LIST
LINKED LIST is a very commonly used linear data structure which consists of group
of nodes in a sequence.
Each node holds its own data and the address of the next node hence forming a
chain like structure.
Linked Lists are used to create trees and graphs.
Let's know more about them and how they are different from each other.
NOTE:
EXAMPLE: Explain how you will retrieve the data in the following link list.
1 C 4
2 D 3
3 E 9
4 I 5
5 R 7
6 F ƛ
7 E 2
→8 K 1
9 R 6
5.TREES
It a nonlinear data structure which represent data in a hierarchical order
A binary tree is composed of zero or more nodes
In Java, a reference to a binary tree may be null
Each node contains:
A value (some sort of data item)
A reference or pointer to a left child (may be null), and
A reference or pointer to a right child (may be null)
A binary tree may be empty (contain no nodes)
If not empty, a binary tree has a root node
Every node in the binary tree is reachable from the root node by a unique path
A node with no left child and no right child is called a leaf
TREE TRAVERSAL
A binary tree is defined recursively: it consists of a root, a left subtree, and a right subtree
To traverse (or walk) the binary tree is to visit each node in the binary tree exactly once
Since a binary tree has three “parts,” there are six possible ways to traverse the binary tree:
ii. Postorder
iii. Inorder
// Assorted methods…
}
A constructor for a binary tree should have three parameters, corresponding to the three fields
Here’s a preorder traversal to print out all the elements in the binary tree:
Here’s an inorder traversal to print out all the elements in the binary tree:
public void inorderPrint(BinaryTree bt) {
if (bt == null) return;
inorderPrint(bt.leftChild);
System.out.println(bt.value);
inorderPrint(bt.rightChild);
}
IN POSTORDER, THE ROOT IS VISITED LAST
Here’s a postorder traversal to print out all the elements in the binary tree:
public void postorderPrint(BinaryTree bt) {
if (bt == null) return;
postorderPrint(bt.leftChild);
postorderPrint(bt.rightChild);
System.out.println(bt.value);
}
THE OTHER TRAVERSALS ARE THE REVERSE OF THESE THREE STANDARD ONES
That is, the right subtree is traversed before the left subtree is traversed
Reverse preorder: root, right subtree, left subtree
Reverse inorder: right subtree, root, left subtree
Reverse postorder: right subtree, left subtree, root
6. GRAPH
Graph is a data structure that consists of a set of nodes (vertices) and a set of edges that
relate the nodes to each other the set of edges describes relationships among the vertices.
adj _ mat[i][ j ]
j 0
Calculate
i. the In-degree where
n 1
ind ( vi ) A[ j , i ]
j 0
n 1
outd ( vi ) A[i , j ]
j 0
3.a. Explain with practical examples how stacks differ from queue? 3mks
b. If pre-order traversal of a pure binary tree is CDKMONQYZ, what will be the post order traversal?
2mks
c.i. construct the adjacency matrix for the following adjacency list 2mks
ANS
ii. What will be the adjacency matrix for the following graph? 3mks
ANS
Explain how you will retrieve the data in the following link list.
1 C 4
2 D 3
3 E 9
4 I 5
5 R 7
6 F ƛ
7 E 2
→8 K 1
9 R 6
91, 92, 93, 94, 95, 96, 97, 89, 99, 100,101,102, 103,104,105,106,107,108,109,110,111.
A tree constructed must have the left nodes of the parent less than the parent node and right nodes
greater than the parent node
What is the different between directed and undirected graph. Explain with specific examples
ANS
UNDIRECTED GRAPH
DIRECTED GRAPH
Both directed and undirected graphs have paths. But in an undirected graph, you may
travel in either direction
a. Array is a container which can hold a fix number of items and these items should be of the same type.
Most of the data structures make use of arrays to implement their algorithms. Develop an algorithm to
implement the following operations of arrays;
a. insertion
b. deletion
c. searching
i. Two of the most common divide-and-conquer sorting algorithms are quick sort and merge sort.
In practice quick sort is often used for sorting data in main storage rather than merge sort. Give
a reason why quick sort is likely to be the preferred sorting algorithm for this application.
ii. There are many different data structures, including the following: List (linked list or array), Tree,
2-dimensional (or higher) array, Binary search tree, Stack, Undirected graph, Queue, Directed
graph, Hash table, Directed Acyclic Graph (DAG). For each of the following applications, indicate
which of these data structures would be most suitable and give a brief justification for your
choice.
Map of the highway system used to display traffic travel times on a web page. The map displays
principle cities, intersections, and major landmarks, the roads that connect them, and the travel times
between them along those roads. Travel times along
7.HASH TABLE
What is Hash table?
A hash table (hash map) is a data structure that implements an associative array abstract data
type, a structure that can map keys to values. A hash table uses a hash function to compute an
index, also called a hash code, into an array of buckets or slots, from which the desired value can
be found. During lookup, the key is hashed and the resulting hash indicates where the
corresponding value is stored.
Explain Linear Probing (open addressing) and Separate Chaining as a technique in dealing with
collision in hashing?
State two application of hash table in computing?
1) Explain Linear Probing and Separate Chaining as a technique in dealing with collision in hashing?
REQUIRED:
Leaner probing scans through the next available space in the hash table when there is a
collision and store the node in there but chaining handles collision by using link list. A scheme
in which each position in the hash table has a list to handle collisions. Each position may be
just a link to the list (direct chaining) or may be an item and a link, essentially, the head of a
list.
2) State two application of hash table in computing?
REQUIRED: some applications
Message Digest
Password Verification
Data Structures(Programming Languages)
Compiler Operation
Rabin-Karp Algortithm
Linking File name and path together
Indicate where the following elements will be located in the hash table provided:
i. @Hash (David) =?
v. ΩHash (Patapaa) =?
REQUIRED
Therefore @hash(David) =8
Mia = 77+105+97 =279 => 279/10 = 27 R 9
# Hash (Mia) =9
$Hash (Frank) =8
&Hash (bigSAM) =1
ΩHash (Patapaa) =6
HASH TABLE
& Ω @ #
APPENDIX
symbol
NOTE: The main advantage of hash tables over other table data structures is speed. This
advantage is more apparent when the number of entries is large. Hash tables are particularly
efficient when the maximum number of entries can be predicted in advance, so that the bucket
array can be allocated once with the optimum size and never resized.
If the set of key-value pairs is fixed and known ahead of time (so insertions and deletions are not
allowed), one may reduce the average lookup cost by a careful choice of the hash function,
bucket table size, and internal data structures. In particular, one may be able to devise a hash
function that is collision-free, or even perfect. In this case the keys need not be stored in the
table.