17Cs1102: Data Structures: Time: 2 Hours Test-1 Key Max. Marks: 50
17Cs1102: Data Structures: Time: 2 Hours Test-1 Key Max. Marks: 50
• When n > 2, the method performs TWO recursive calls, one with the parameter
n - 1 , another with parameter n – 2, and some constant # of basic operations.
T(n) =c if n = 1 or n = 2
T(n) = T(n – 1) + T(n – 2) + b if n > 2
We determine a lower bound on T(n):
Expanding: T(n) = T(n - 1) + T(n - 2) + b 2M
≥ T(n - 2) + T(n-2) + b
= 2T(n - 2) + b
= 2[T(n - 3) + T(n - 4) + b] + b by substituting T(n - 2)
in (2)
2[T(n - 4) + T(n - 4) + b] + b
= 22T(n - 4) + 2b + b
= 22[T(n - 5) + T(n - 6) + b] + 2b + b by substituting T(n - 4)
in (2)
≥ 23T(n – 6) + (22 + 21 + 20)b
...
k k-1
2 T(n – 2k) + (2 + 2k-2 + . . . + 21 + 20)b
= 2kT(n – 2k) + (2k – 1)b
The base case isreachedwhen n – 2k = 2 k = (n - 2) / 2
(n – 2) / 2 (n - 2) / 2
Hence T(n) ≥ 2 T(2) + [2 – 1]b
(n – 2) / 2
= (b + c)2 –b
= [(b + c) / 2]*(2)n/2 – b Recursive Fibonacci is exponential.
2. Design Shell sort routine using Shell’s increments. Trace Shell sort after
each pass for an array A = <81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15>
– 4M
Answer :
Shell Sort 2M
Improves on insertion sort.
Starts by comparing elements far apart, then elements less far apart,
and finally comparing adjacent elements (effectively an insertion sort).
By this stage the elements are sufficiently sorted that the running time
of the final stage is much closer to O(N) than O(N2).
81 28 11 41 12 15 17
95 94 58 96 75 35
The sorted list as PASS 7: 81 28 11 41 12 15 17 95 94 58 96 75 35.
Step 2:Arrange the above array list in 5 columns, sort columns wise.
81 28 11 41 12 15 17 11 41 12
15 17 95 94 58 -> 81 28 35 94 58
96 75 35 96 75 95
The sorted list at AFTER 5 SORT: 15,17,11,41,12,81,28,35,94,58,96,75,95.
STEP 3: arrange the above updated array list in 3 columns
15 17 11 15 12 11
41 12 81 - 28 17 75
28 35 94 41 35 81
58 96 75 58 96 94
95 95
The updated array at this stage is : 15,12,11,28,17,75,41,35,81,58,96,94,95.
Step 4: Arrange the above list in 1 column and sort the array
15
12
11
28
17
75
41
35
81
58
96
94
95
After 1-sort 11 12 15 17 28 35 41 58 75 81 94 95 96.
Routine: 2M
void shellsort( int a[ ], unsigned int n )
{
unsigned int i, j, increment;
int tmp;
/*1*/ for( increment = n/2; increment > 0; increment /= 2 )
/*2*/ for( i = increment+1; i<=n; i++ )
{
/*3*/ tmp = a[i];
/*4*/ for( j = i; j > increment; j -= increment )
/*5*/ if( tmp< a[j-increment] )
/*6*/ a[j] = a[j-increment];
else
/*7*/ break;
/*8*/ a[j] = tmp;
}
}.
3 . Develop an algorithm to insert an element in ith position of doubly linked
list.
-4M
Temp->right=p->right;
p->right->left=temp;
p->right=temp;
temp->left=p;
}
}
4. Define divide and conquer strategy. State three steps of Merge sort. Write
the recursive merge-sort algorithm that takes an array as its input and gives
output. -4M
Answer:
Divide and Conquer: -1M
Divide and Conquer is an algorithmic paradigm. A typical Divide and Conquer
algorithm solves a problem using following three steps.
1. Divide: Break the given problem into subproblems of same type. -1M
2. Conquer: Recursively solve these subproblems
3. Combine: Appropriately combine the answers
Merge Sort is also a sorting algorithm follow Divide and Conquer strategy.
1. The algorithm divides the array in two halves,
2. Recursively sorts them and
3. Finally merges the two sorted halves.
void m_sort( int a[], input_type tmp_array[ ], int left, int right ) -2M
{
int center;
if( left < right )
{
center = (left + right) / 2;
m_sort( a, tmp_array, left, center );
m_sort( a, tmp_array, center+1, right );
merge( a, tmp_array, left, center+1, right );
}
for(i=left;i<right;i++)
{
printf(“%d\t”,A[i]);
}
}
void merge( int a[ ], int tmp_array[ ], int l_pos, int r_pos, int right_end )
{
int i, left_end, num_elements, tmp_pos;
left_end = r_pos - 1;
tmp_pos = l_pos;
num_elements = right_end - l_pos + 1;
/* main loop */
while( ( 1_pos <= left_end ) && ( r_pos <= right_end ) )
if( a[1_pos] <= a[r_pos] )
tmp_array[tmp_pos++] = a[l_pos++];
else
tmp_array[tmp_pos++] = a[r_pos++];
while( l_pos <= left_end ) /* copy rest of first half */
tmp_array[tmp_pos++] = a[l_pos++];
while( r_pos <= right_end ) /* copy rest of second half */
tmp_array[tmp_pos++] = a[r_pos++];
/* copy tmp_array back */
for(i=1; i <= num_elements; i++, right_end-- )
a[right_end] = tmp_array[right_end];
}
5. Develop a program to find the solution for the maximum subsequence
sum problem with logarithmic time. -4M
int max_sub_sequence_sum( int a[], unsigned int n ) -1M
{
return max_sub_sum( a, 0, n-1 );
}
This method can also be optimized to work in O(1) by keeping an extra pointer to tail
of linked list.
Answer:
Here in the below code we are changing the head pointing address in terms of pointer
to pointer reference, means address of head is passed from main() and its content is
being modified in stack_reverse function itself.
Struct node 1M
{
Int data;
Struct node *next;
};
if (*head == NULL)
{
printf("Stack does not exist\n");
}
else if ((*head)->next == NULL)
{
printf("Single node stack reversal brings no difference\n");
}
else if ((*head)->next->next == NULL)
{
(*head)->next->next = *head;
*head = (*head)->next;
(*head)->next->next = NULL;
}
else
{
prev = *head;
temp = (*head)->next;
*head = (*head)->next->next;
prev->next = NULL;
while ((*head)->next != NULL)
{
temp->next = prev;
prev = temp;
temp = *head;
*head = (*head)->next;
}
temp->next = prev;
(*head)->next = temp;
}
}
Time complexity of delete a node from end position is O(n), where n is the number
of nodes in linked list. Since there is a loop from head to end, the function does O(n)
work. 2M
8. Write and Analyze an algorithm to convert the given infix expression
into postfix and prefix expression for: (A – B) / ((D + E) * F). -6M
Answer:
Infix to Postfix Conversion Algorithm -2M
Let Q be any infix expression and we have to convert it to postfix expression P. For
this the following procedure will be followed.
1. Push left parenthesis onto STACK and add right parenthesis at the end of Q.
2. Scan Q from left to right and repeat step 3 to 6 for each element of Q until the
STACK is empty.
3. If an operand is encountered add it to P.
4. If a left parenthesis is encountered push it onto the STACK.
5. If an operator is encountered, then
Repeatedly pop from STACK and add to P each operator
which has same precedence as or higher precedence than the operator
encountered.
Push the encountered operator onto the STACK.
6. If a right parenthesis is encountered, then
Repeatedly pop from the STACK and add to P each operator
until a left parenthesis is encountered.
Remove the left parenthesis; do not add it to P.
7. Exit
( (/ ( FED+*
Postfix :FED+*BA-/
Step 5: Reverse the string
Prefix expression is /–AB*+DEF -1M
The algorithm will take O(n) where n is the length of the string . The push and pop
operation in the stack will also in the time complexity of O(n). Hence , time
complexity is O(n) -1M
Answer:
Sorting data 3M
Algorithm 3M
Below is a simple implementation of bucket sort. It uses half the number of buckets
as the numbers of elements in the sequence to store. It goes through all the
elements in the sequence, and stores them in buckets. The bucket number to store
the element at is given by a hash function. The hash function assumes numbers in
sequence are uniformly distributed. Each bucket as a linked list to dynamically store
as many elements as it needs.
buckets[bucket_numb].size);
/* instead, we could store in-order, and then we wouldn't have to apply
sorting to each list */
}
/* go through all buckets. Get elements out and overwrite sequence.
Then order the section of sequence with elements from bucket */
j = 0;
node_t *prev;
for (i = 0; i < numb_buckets; i++) {
if (buckets[i].size > 0) {
left = j;
node_t *listptr = buckets[i].list;
while (listptr != NULL) {
seq[j++] = listptr->data;
printf("Retrieved %d from bucket %d\n", seq[j-1], i);
prev = listptr;
listptr = listptr->next;
free(prev); /* deallocate memory */
}
/* sort subarray */
insertsort(seq, left, j);
}
}
}
void insertsort(int *seq, int left, int right) {
int i, j, element;
for (i = left + 1; i < right; i++) {
element = seq[i];
for (j = i-1; i >=0 && seq[j] > element; j--) {
seq[j+1] = seq[j];
}
seq[j+1] = element;
}
}
int hash(int value, int numb_buckets, int max){
/* for an uniform distribution, this hash should give the best
distribution of numbers throughout the buckets */
int key = value * numb_buckets / max;
return key;
}
10. Write a routine to perform insert and delete operations on single linked
list. Develop a routine to find whether the given elements in the single
linked list are unique (without duplication) or not and prove that it takes
quadratic time. -12M
Answer:
typedef struct list 4M
{
int data;
struct list *link;
}node;
Ans:
#include <stdio.h> 2M
Void swap ( int* a, int* b )
{
intt = *a;
*a = *b;
*b = t;
}
inttop = -1;
stack[ ++top ] = l;
stack[ ++top ] = h;
while( top>= 0 )
{
h = stack[ top-- ];
l = stack[ top-- ];
intp = partition( arr, l, h );
if( p-1 > l )
{
stack[ ++top ] = l;
stack[ ++top ] = p - 1;
}
if( p+1 < h )
{
stack[ ++top ] = p + 1;
stack[ ++top ] = h;
}
}
}
Int main() 2M
{
Int arr[] = {4, 3, 5, 2, 1, 3, 2, 3};
intn = sizeof( arr ) / sizeof( *arr );
quickSortIterative( arr, 0, n - 1 );
printArr( arr, n );
return0;
}