Assignment02 (SP24-BSE-047)
Assignment02 (SP24-BSE-047)
ASSIGNMENT 02
Reg-no: - SP24-BSE-047
Question # 1
Indicate whether a stack would be a suitable data structure for each of the following application. Justify your
answer.
Application Stack Suitable or not[Y/N] Reason
A bank simulation of its teller N Queue is more suitable for
operation to see how waiting times simulating waiting lines (FIFO).
would be affected by adding
1
another teller
An address book N Requires random access and
search, not LIFO behavior.
A program to receive data that are Y Stack provides LIFO behavior.
to be saved and processes in the
reverse order
A word processor to have a PF key Y Stack can store command history
that causes the preceding command (LIFO).
to be redisplayed. Every time the
user press the PF key, the program
shows the command that preceded
the one currently displayed.
A program to evaluate arithmetic Y Stack helps evaluate expressions
expressions according to the in correct order (e.g., postfix).
specific order of operators
A dictionary of words used by a N Requires search and retrieval, not
spelling checker to be built and LIFO structure.
maintained
A data structure used to keep track Y Stack tracks return points during
of return addresses for nested function calls (LIFO).
function while a program is
running
A program to keep track of patients N Queue is suitable for first-come,
as they check into a medical clinic, first-served systems.
assigning patient to doctor on a
first come, first served basis
Question # 2
Two stacks of positive integers are needed, one containing elements with values less than or equal to 1,000
and other containing elements with values larger than 1,000. The total number of elements in the small – value
stack and the large – value stack combined are not more than 200 at any time, but we cannot predict how
many are in each stack. (All of the elements could be in the small –value stack, they could be evenly divided,
both stacks could be empty, and so on). Can you think of a way to implement both stacks in one array?
a) Draw a diagram of how the stack might look.
b) Write the definitions for such a double – stack structure.
c) Write the algorithm for Push operation; it should store the new item into the correct stack according to
its value.
S1 S1 S2 S2
topSmall topLarge
Part B.
2
define MAX_SIZE = 200
define THRESHOLD = 1000
structure DoubleStack:
array: Array[MAX_SIZE] of integers
topSmall: integer = -1 // index for small-value stack
topLarge: integer = MAX_SIZE // index for large-value stack
end structure
Part C.
Question # 3
In each plastic container of Pez candy, the colors are stored in random order (See figure below).
Your little brother likes only yellow ones, so he painstakingly takes out all the candies, one by one, eats the
yellow ones, and keeps the other in order, so that he can return them to container in exactly the same order as
before- minus the yellow candies, of course. Write the algorithm to simulate this process. You may use any of
the stack operations defined in the stack ADT, but may not assume any knowledge of stack’s implementation.
ANSWER IN THIS BOX
Algorithm: RemoveYellowCandies
Input: A stack S containing randomly ordered candies (including yellow ones)
3
Output: The same stack without yellow candies, maintaining original order of others
1. Create an empty temporary stack tempStack
2. While S is not empty:
a. currentCandy = Pop(S)
b. If currentCandy is not yellow:
Push(currentCandy, tempStack)
3. While tempStack is not empty:
a. Push(Pop(tempStack), S)
4. Return S
i. Draw a schematic diagram about how to plan six stacks in a single array.
ii. How would you implement a stack of stack?
Part 1:
ARRAY
Part 2:
PUSH Algorithm:
Algorithm PushStackOfStacks(mainStack, innerStack):
if mainStack is full:
throw "Stack Overflow"
mainStack.top += 1
mainStack.array[mainStack.top] = innerStack
POP Algorithm:
Algorithm PopStackOfStacks(mainStack):
if mainStack is empty:
throw "Stack Underflow"
innerStack = mainStack.array[mainStack.top]
4
mainStack.top -= 1
return innerStack
2. A ^ B * C – D + E/F
3. A/(B+C*D-E)
4. A-B*C+D/E
5. (A+B)^2 -(C-D)/2
Question # 5
What is the value of the postfix expression? Write each step of this conversion.
1. AB+CD–*
2. A B ^ C*D – E F/+
3. ABCD*+E-/
4. ABC*-DE/+
5. AB+2 ^CD-2/-
Where A = 12 , B = 3 ,C = 7 , D = 4 ,E = 2 and F = 5
Question # 6
i. Write an algorithm for converting an infix expression into prefix expression
5
ii. Write an algorithm for evaluation of prefix expression
ANSWER IN THIS BOX
Infix to Prefix:
Prefix Evaluation:
Question # 7
i. Convert the following infix expression into equivalent prefix expression
A^B*C-D+E/F/(G+G)
ii. Evaluate the following prefix expression:
+ A*B+CD if A =2 , B =3, C = 4, D = 5
Question # 8
The efficient method used in evaluating a polynomial of the form
Algorithm: EvaluatePolynomial
6
2. Push aₙ onto S
3. For each coefficient aᵢ from aₙ₋₁ to a₀:
a. top = Pop(S)
b. result = top * x + aᵢ
c. Push(result, S)
4. Final result is Pop(S)
Question # 9 (Recursion)
Consider the following recursion for integer multiplication of two positive number a and b:
a* 1 = a
a*b = a(b -1) + a
This can be implemented using following recursive algorithm as follows:
Algorithm recursive_multiplication(a, b)
if b = 1 then
return a
else
return a + recursive_multiplication ( a, b-1)
a) Convert above recursive algorithm in to an iterative algorithm? Present your iterative version into
Pseudo code.
b) Mathematically the following definition for integer multiplication is valid:
a multiply by b : a*b = a(b+1) – a
Can we have recursive algorithm for calculating integer multiplication based on above definition?
Explain carefully.
Question # 10
Determine whether a recursive or iterative solution is most appropriate for GCD problem
Iterative version Recursive version
ALGORITHM M_Euclid_iterative(m, n) ALGORITHM M_Euclid_recursive(m, n)
// Input: m ≥ 0 n ≥ 0 // Input: Two non-negative integers m and n, not both
7
// Output: Greatest Common Divisor of m and n zero.
while n ≠ 0 do // Output: Greatest Common Divisor of m and n
if m < n then if m = 0 then
swap(m, n) ans ← n
m ← m- n else if m > n then
return m ans ← M_Euclid(n, m)
else
nLess ← n- m
ans ← M_Euclid(m, nLess)
return ans
Question # 11
i. Consider the following two algorithms Algorithm A and Algorithm B that solve
same problem P. Explain what these algorithms compute?
Both algorithms use recursion but solve different problems. Algorithm A has O(n) time complexity while
Algorithm B has exponential time complexity O(2^n) in its naive recursive form.
Question # 12
Consider the problem of compute the factorial function F(n) = n! for an arbitrary
nonnegative integer n. Which of the algorithm iterative or recursive is most efficient.
Justify your answer.
8
ANSWER IN THIS BOX
The iterative version is more efficient for computing factorial because:
Question # 13
Consider the following two algorithms for computing n th term of Fibonacci sequence, F(n). One is iterative
and other is recursive.
ITERATIVE ALGORITHM:
RECURSIVE ALGORITHM:
Which of the algorithm iterative or recursive is most efficient. Justify your answer.
Question # 14
Consider the following problem:
Problem: Compute an where a ≠ 0 and n is a nonnegative
Inorder to solve a given problem using recursion, we split it into smaller subproblem. Here is various strategy
for splitting into smaller subproblem. Youhave to design recursive algorithm for each of the strategy
Model Algorithm
an = an-1 × a 1. Algorithm PowerLinear(a, n):
2. if n == 0 then
3. return 1
4. else
5. return a * PowerLinear(a, n-1)
(an/2 ) 2 if n is even and positive 1. Algorithm PowerDivideConquer(a, n):
an = (a(n-1)/2 ) 2 * a if n is odd and > 1 2. if n == 0 then
3. return 1
a if n = 1 4. else if n == 1 then
5. return a
6. else if n % 2 == 0 then
7. half = PowerDivideConquer(a, n/2)
8. return half * half
9. else
10. half = PowerDivideConquer(a, (n-1)/2)
11. return half * half * a
a ë n/2 û * a é n/2 ù if n > 1 1. Algorithm PowerFloorCeiling(a, n):
n
a= a if n = 1 2. if n == 0 then
3. return 1
4. else if n == 1 then
5. return a
6. else
7. left = PowerFloorCeiling(a, floor(n/2))
8. right = PowerFloorCeiling(a, ceil(n/2))
9. return left * right
10
Most Efficient Algorithm: Model 2
Because it:
Question # 15
Indicate whether each of the following application would be a suitable for a queue. Justify your answer.
Question # 16
Write an algorithm that will reverse all the elements in a queue
ANSWER IN THIS BOX
Algorithm ReverseQueue(Q):
11
Create an empty stack S
While Q is not empty:
Push(Dequeue(Q), S)
While S is not empty:
Enqueue(Pop(S), Q)
Return Q
Question # 17
i. How would you implement a queue of stacks?
ii. How would you implement a stack of queues?
iii. How would you implement a queue of queues?
a. Draw a diagram of how each of these data structures might look.
b. Write algorithms/ routines to implement the appropriate operations of each of these data
structures
ANSWER IN THIS BOX
Part 1.
i. Queue of stacks:
Part 2.
ii. Stack of queues:
1. Each element in the stack is a queue
2. Push: Add a new queue on top
3. Pop: Remove the top queue
Part 3.
Question # 18
Write algorithms (for insertion and deletion) that implement two queues in one array where first queue will
start from 0th position and second queue will start from last position of the array.
12
Q.rear1 = Q.rear1 + 1
Algorithm Dequeue1(Q):
if Q.front1 == Q.rear1 then
throw "Queue Underflow"
x = Q.array[Q.front1]
Q.front1 = Q.front1 + 1
return x
Algorithm Dequeue2(Q):
if Q.front2 == Q.rear2 then
throw "Queue Underflow"
x = Q.array[Q.front2]
Q.front2 = Q.front2 - 1
return x
Question # 19
Write an algorithm that uses stack in order to reverse the elements of a circular queue, which is stored in an
array. For example, if the initial queue is that given in Fig-1 as under, then the resulting Queue is that given in
Fig-2.
Algorithm ReverseCircularQueue(Q):
Create an empty stack S
// Transfer all elements to stack
while not Q.isEmpty():
Push(S, Q.dequeue())
// Transfer back to queue
while not S.isEmpty():
Q.enqueue(Pop(S))
return Q
13
Question # 20
It is required to split a circular queue into two circular queues (say CQueue1 and CQueue 2) so that all the
elements in odd positions are in one queue and those in even positions are in another queue as shown in the
following figure. Write a C++ program to accomplish this. Assume that queue is maintained in an array.
CQueue2:
CQueue1:
Before
int main() {
const int SIZE = 6;
int original[SIZE] = {10, 20, 30, 40, 50, 60};
int queue1[SIZE/2 + 1], queue2[SIZE/2];
14
cout << queue2[i] << " ";
}
return 0;
}
Question # 21
Can a queue be represented by a circular linked list with only one pointer pointing to the tail of the queue.
Write C++ functions for add and delete operations on such a queue.
struct Node {
int data;
Node* next;
Node(int d) : data(d), next(nullptr) {}
};
class CircularQueue {
private:
Node* tail;
public:
CircularQueue() : tail(nullptr) {}
void enqueue(int x) {
Node* newNode = new Node(x);
if (tail == nullptr) {
tail = newNode;
tail->next = tail;
} else {
newNode->next = tail->next;
tail->next = newNode;
tail = newNode;
}
}
int dequeue() {
if (tail == nullptr) {
throw "Queue Underflow";
}
int x;
if (tail->next == tail) {
x = tail->data;
delete tail;
tail = nullptr;
} else {
15
Node* temp = tail->next;
x = temp->data;
tail->next = temp->next;
delete temp;
}
return x;
}
};
Question # 22
A DEQUE is a data structure consisting of a list of items, on which the following operations are possible:
PUSH ( X,D) : Insert item X on the front end of DEQUE D.
POP(D) : Remove the front item from DEQUE D and return it.
Inject(X, D) : Insert item X on the rear end of DEQUE D.
Eject(D) : Remove the rear item from DEQUE D and return it.
Write C++ program (complete program) that support the above DEQUE operations.
class Deque {
private:
int arr[MAX_SIZE];
int front, rear, size;
public:
Deque() : front(-1), rear(0), size(0) {}
void push(int x) {
if (isFull()) {
cout << "Deque Overflow\n";
return;
}
if (front == -1) {
front = rear = 0;
} else if (front == 0) {
front = MAX_SIZE - 1;
} else {
front--;
}
arr[front] = x;
16
size++;
}
void inject(int x) {
if (isFull()) {
cout << "Deque Overflow\n";
return;
}
if (front == -1) {
front = rear = 0;
} else if (rear == MAX_SIZE - 1) {
rear = 0;
} else {
rear++;
}
arr[rear] = x;
size++;
}
int pop() {
if (isEmpty()) {
throw "Deque Underflow";
}
int x = arr[front];
if (front == rear) {
front = -1;
rear = 0;
} else if (front == MAX_SIZE - 1) {
front = 0;
} else {
front++;
}
size--;
return x;
}
int eject() {
if (isEmpty()) {
throw "Deque Underflow";
}
int x = arr[rear];
if (front == rear) {
front = -1;
rear = 0;
} else if (rear == 0) {
rear = MAX_SIZE - 1;
} else {
rear--;
17
}
size--;
return x;
}
};
18