Data Structures (KCS301)
Data Structures (KCS301)
TECH
DATA STRUCTURES
function foo(data) {
a(data);
return b(data);
}
1d. write the full and empty condition for circular queue data structure
Ans: In a Linear queue, once the queue is completely full, it's not possible to insert more
elements. Even if we dequeue the queue to remove some of the elements, until the queue is
reset, no new elements can be inserted. You must be wondering why?
Finds the key present at first position in constant Finds the key present at center position in
time constant time
1g.
1h. Write shot notes on adjacency multi list representation a graph.
Ans: An edge in an undirected graph is represented by two nodes in adjacency list
representation. Adjacency Multi lists: lists in which nodes may be shared among several lists.
1i. What is the importance of threaded binary tree?
Ans: Inorder traversal of a Binary tree can either be done using recursion or with the use of
a auxiliary stack. The idea of threaded binary trees is to make inorder traversal faster and
do it without stack and without recursion. A binary tree is made threaded by making all
right child pointers that would normally be NULL point to the inorder successor of the
node (if it exists).
There are two types of threaded binary trees.
Single Threaded: Where a NULL right pointers is made to point to the inorder successor (if
successor exists)
Double Threaded: Where both left and right NULL pointers are made to point to inorder
predecessor and inorder successor respectively. The predecessor threads are useful for
reverse inorder traversal and postorder traversal.
The threads are also useful for fast accessing ancestors of a node.
Following diagram shows an example Single Threaded Binary Tree. The dotted lines
represent threads.
Section B
2a. Consider a multi-dimensional array Array[90][30][40] with base address starts at
1000. Calculate the address of A[10][20][30] in row major order and column major
order. Assume the first element is stored at A[2][2][2] and each element take 2 byte.
Ans 2C: Hash table is a data structure in which keys are mapped to array positions by a hash
function.
Hash table, an element with key k is stored at index h(k) and not k.
It means a hash function h is used to calculate the index at which the element with key k will
be stored.
Hash table in which each key from the set k is mapped to locations generated by using a hash
function.
When two or more keys map to same memory location is known as collision.
The process of mapping the keys to appropriate locations in a hash table is called hashing.
Different Hash Functions:
1. Division Method
2. Multiplication method
3. Mid Square Method
4. Folding Method
Division Modulo Method
• It is the simplest method of hashing an integer k.
• The method divides k by M and then uses the remainder thus obtained.
• h(k)= k mod M
Where k is the key and M is the Size of the hash table.
Multiplication Method:
1. Choose a constant A such that 0 < A <1.
2. Multiply the key k by A.
3. Extract the fractional part of kA.
4. Multiply the result of step 3 by m and take the floor.
h(k) = |m (kA mod 1) |
Mid-Square Method:
1. Square the value of the key. i.e. k2.
2. Extract the middle r bits of the result obtained in step 1.
h(k) = k2
In this part of the tutorial we will discuss the techniques by using which, we can traverse all
the vertices of the graph.
Traversing the graph means examining all the nodes and vertices of the graph. There are two
standard methods by using which, we can traverse the graphs. Lets discuss each one of them
in detail.
Breadth first search is a graph traversal algorithm that starts traversing the graph from root
node and explores all the neighbouring nodes. Then, it selects the nearest node and explore all
the unexplored nodes. The algorithm follows the same process for each of the nearest node
until it finds the goal.
The algorithm of breadth first search is given below. The algorithm starts with examining the
node A and all of its neighbours. In the next step, the neighbours of the nearest node of A are
explored and process continues in the further steps. The algorithm explores all neighbours of
all the nodes and ensures that each node is visited exactly once and no node is visited twice.
Algorithm
o Step 1: SET STATUS = 1 (ready state)
for each node in G
o Step 2: Enqueue the starting node A
and set its STATUS = 2
(waiting state)
o Step 3: Repeat Steps 4 and 5 until
QUEUE is empty
o Step 4: Dequeue a node N. Process it
and set its STATUS = 3
(processed state).
o Step 5: Enqueue all the neighbours of
N that are in the ready state
(whose STATUS = 1) and set
their STATUS = 2
(waiting state)
[END OF LOOP]
o Step 6: EXIT
Example
Consider the graph G shown in the following image, calculate the minimum path p from node
A to node E. Given that each edge has a length of 1.
Solution:
Minimum Path P can be found by applying breadth first search algorithm that will begin at
node A and will end at E. the algorithm uses two queues,
namely QUEUE1 and QUEUE2. QUEUE1 holds all the nodes that are to be processed
while QUEUE2 holds all the nodes that are processed and deleted from QUEUE1.
1. QUEUE1 = {A}
2. QUEUE2 = {NULL}
2. Delete the Node A from QUEUE1 and insert all its neighbours. Insert Node A into QUEUE2
1. QUEUE1 = {B, D}
2. QUEUE2 = {A}
3. Delete the node B from QUEUE1 and insert all its neighbours. Insert node B into QUEUE2.
1. QUEUE1 = {D, C, F}
2. QUEUE2 = {A, B}
4. Delete the node D from QUEUE1 and insert all its neighbours. Since F is the only neighbour
of it which has been inserted, we will not insert it again. Insert node D into QUEUE2.
1. QUEUE1 = {C, F}
2. QUEUE2 = { A, B, D}
5. Delete the node C from QUEUE1 and insert all its neighbours. Add node C to QUEUE2.
1. QUEUE1 = {F, E, G}
2. QUEUE2 = {A, B, D, C}
6. Remove F from QUEUE1 and add all its neighbours. Since all of its neighbours has already
been added, we will not add them again. Add node F to QUEUE2.
1. QUEUE1 = {E, G}
2. QUEUE2 = {A, B, D, C, F}
7. Remove E from QUEUE1, all of E's neighbours has already been added to QUEUE1
therefore we will not add them again. All the nodes are visited and the target node i.e. E is
encountered into QUEUE2.
1. QUEUE1 = {G}
2. QUEUE2 = {A, B, D, C, F, E}
2e.
STEP 5: SET I = 0
C Program for insertion at the nth node of the Singly Linked List:-
#include <stdio.h>
#include <stdlib.h>
struct node *head=NULL;
struct node
{
int data;
struct node *next;
};
ptr->next=temp->next; //Make the newly created node point to next node of ptr temp
temp->next=ptr; //Make ptr temp point to newly created node in the linked list
}
void display()
{
struct node *temp=head;
printf("\nList: ");
while(temp!=NULL)
{
printf("\n%d ",temp->data);
temp=temp->next;
}
}
int main()
{
int i, n, pos, data;
printf("Enter the number of nodes: \n");
scanf("%d",&n);
printf("Enter the data for the nodes: \n");
for(i=0;i<n;i++)
{
scanf("%d",&data);
ins(data);
}
printf("Enter the data you want to insert in between the nodes: \n");
scanf("%d",&data);
printf("Enter the position at which you want to insert the nodes: \n");
scanf("%d",&pos);
if(pos>n)
{
printf("Enter a valid position: ");
}
else
{
ins_at_pos_n(data,pos);
}
display();
return 0;
}
Output:-
Enter the number of nodes:
5
Enter the data for the nodes:
44
5
22
6
95
Enter the data you want to insert in between the nodes:
100
Enter the position at which you want to insert the nodes:
4
List:
44
5
22
100
6
95
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *next;
}*top = NULL; // Initially the list is empty
void push(int);
void pop();
void display();
int main()
{
int choice, value;
printf("\nIMPLEMENTING STACKS USING LINKED LISTS\n");
while(1){
printf("1. Push\n2. Pop\n3. Display\n4. Exit\n");
printf("\nEnter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1: printf("\nEnter the value to insert: ");
scanf("%d", &value);
push(value);
break;
case 2: pop();
break;
case 3: display();
break;
case 4: exit(0);
break;
default: printf("\nInvalid Choice\n");
}}}
void pop()
{
if(top == NULL)
printf("\nEMPTY STACK\n");
else{
struct Node *temp = top;
printf("\nPopped Element : %d", temp->data);
printf("\n");
top = temp->next; // After popping, make the next node as TOP
free(temp);
}}
void display()
{
// Print the stack
if(top == NULL)
printf("\nEMPTY STACK\n");
else
{
printf("The stack is \n");
struct Node *temp = top;
while(temp->next != NULL){
printf("%d--->",temp->data);
temp = temp -> next;
}
printf("%d--->NULL\n\n",temp->data);
}}
5a. Write an algorithm for merge sort and apply on following elements
45,32,65,76,23,12,54,67,22,87
Ans: Algorithm for Merge Sort:
Merge sort is one of the most efficient sorting algorithms. It works on the principle of Divide
and Conquer. Merge sort repeatedly breaks down a list into several sublists until each sublist
consists of a single element and merging those sublists in a manner that results into a sorted
list.
Merge sort is a sorting technique based on divide and conquer technique. With worst-case
time complexity being Ο(n log n), it is one of the most respected algorithms.
Merge sort first divides the array into equal halves and then combines them in a sorted manner.
How Merge Sort Works?
To understand merge sort, we take an unsorted array as the following −
We know that merge sort first divides the whole array iteratively into equal halves unless the
atomic values are achieved. We see here that an array of 8 items is divided into two arrays of
size 4.
This does not change the sequence of appearance of items in the original. Now we divide these
two arrays into halves.
We further divide these arrays and we achieve atomic value which can no more be divided.
Now, we combine them in exactly the same manner as they were broken down. Please note
the color codes given to these lists.
We first compare the element for each list and then combine them into another list in a sorted
manner. We see that 14 and 33 are in sorted positions. We compare 27 and 10 and in the target
list of 2 values we put 10 first, followed by 27. We change the order of 19 and 35 whereas 42
and 44 are placed sequentially.
In the next iteration of the combining phase, we compare lists of two data values, and merge
them into a list of found data values placing all in a sorted order.
After the final merging, the list should look like this −
Algorithm
Merge sort keeps on dividing the list into equal halves until it can no more be divided. By
definition, if it is only one element in the list, it is sorted. Then, merge sort combines the
smaller sorted lists keeping the new list sorted too.
Step 1 − if it is only one element in the list it is already sorted, return.
Step 2 − divide the list recursively into two halves until it can no more be divided.
Step 3 − merge the smaller lists into new list in sorted order.
// Storing element
elements[ind] = arr[i];
// Driver code
void main()
{
int arr[] = { 6, 7, 8, 9, 10 };
int n = sizeof(arr) / sizeof(arr[0]);
// Element to search
int k = 8;
indexedSequentialSearch(arr, n, k);
}