stack
stack
Question 1:
Answer:
A stack is a linear data structure that follows the Last In First Out (LIFO) order, meaning the
last element added is the first one to be removed. It is similar to a stack of plates, where the plate
added last is the one that is removed first.
Basic Operations:
Example:
Stack = []
Push 10 → [10]
Push 20 → [10, 20]
Pop → [10] (removes 20)
Question 2:
Answer:
1. Push: O(1) - Adding an element to the top of the stack takes constant time.
2. Pop: O(1) - Removing the top element from the stack takes constant time.
3. Peek: O(1) - Accessing the top element without removing it takes constant time.
4. isEmpty: O(1) - Checking if the stack is empty takes constant time.
Since these operations only involve adding, removing, or accessing the top element, they all
operate in constant time.
Question 3:
Answer:
The key difference between a stack and a queue is in the order of operations:
1. Stack:
oFollows the Last In First Out (LIFO) principle.
oThe last element added is the first one to be removed.
2. Queue:
o Follows the First In First Out (FIFO) principle.
o The first element added is the first one to be removed.
Example:
Question 4:
Answer:
1. Function Call Stack: Used in recursion where function calls are pushed onto the stack
and popped when the function returns.
2. Expression Evaluation: Used in parsing and evaluating arithmetic expressions (infix,
postfix, prefix).
3. Undo Operation: In applications, stacks are used to keep track of user actions so that
they can be undone.
4. Backtracking Algorithms: Used in algorithms like depth-first search (DFS) for
exploring nodes.
Question 5:
Answer:
A stack overflow occurs when a program tries to use more stack space than is allocated,
typically when there are too many function calls in a program (such as infinite recursion) or too
many elements are pushed onto the stack. This results in a runtime error or crash.
Example: In recursive functions, if the base case is not properly defined, the function might call
itself indefinitely, leading to a stack overflow.
Question 6:
Answer:
The isEmpty operation is used to check whether the stack is empty. It returns true if the stack
has no elements, and false if there are elements in the stack.
Example:
Code Example:
if (stack.isEmpty()) {
// Stack is empty
} else {
// Stack has elements
}
Time Complexity: O(1), as it involves just checking the top of the stack.
Question 7:
Answer:
Stack underflow occurs when an attempt is made to pop or peek an element from an empty
stack. Since there are no elements in the stack, performing these operations leads to an error,
usually resulting in a runtime exception.
Example:
If the stack is empty and a pop operation is called, it will result in a stack underflow.
Code Example:
if (stack.isEmpty()) {
// Error: Stack underflow
} else {
stack.pop();
}
Question 8:
What is a stack implemented using an array? Explain how elements are pushed and
popped.
Answer:
A stack implemented using an array stores elements in a contiguous block of memory, and an
integer is used to track the top of the stack.
Push Operation: Adds an element to the stack by placing it at the index pointed to by the top
pointer, and then increments top.
Pop Operation: Removes the element from the stack by decrementing the top pointer and then
returning the element at that position.
Example:
#define MAX 5
int stack[MAX];
int top = -1; // Initially, stack is empty.
int pop() {
if (top == -1) {
printf("Stack Underflow\n");
} else {
return stack[top--]; // Return the element and decrement top
}
}
Time Complexity:
o Push: O(1)
o Pop: O(1)
Question 9:
Answer:
The stack and heap are both memory regions used for storing data, but they differ in how
memory is allocated and managed:
1. Stack:
o Memory allocation is automatic and follows LIFO (Last In First Out) order.
o Memory is used for function calls, local variables, and the program's call stack.
o Memory is limited and can cause stack overflow when it exceeds the limit.
2. Heap:
o Memory allocation is manual, done via functions like malloc() in C.
o Used for dynamic memory allocation, such as objects created at runtime.
o Memory is more flexible and does not have size limits like the stack, but memory must
be freed explicitly to avoid memory leaks.
Question 10:
Answer:
The Top variable in a stack is an integer that keeps track of the index of the topmost element in
the stack. It is critical in performing push, pop, and peek operations, as it allows direct access to
the element at the top of the stack.
Example:
int stack[MAX];
int top = -1; // Stack is empty initially.
Question 11:
Answer:
In recursion, each function call is stored in the call stack. When a function calls itself, the state
(variables and control) of the current function is saved onto the stack. Once the base case is
reached, the functions are popped from the stack and their results are returned in reverse order of
function calls.
Example: In a recursive function calculating factorial, each function call is pushed onto the stack
until the base case is met.
Factorial Example:
int factorial(int n) {
if (n == 0) return 1; // Base case
else return n * factorial(n-1); // Recursive case
}
Question 12:
Answer:
A stack is commonly used in expression evaluation, particularly for evaluating infix, prefix,
and postfix expressions.
Postfix Expression (Reverse Polish Notation): Operands are followed by operators. The
stack is used to store operands, and when an operator is encountered, the top elements are
popped, the operation is performed, and the result is pushed back onto the stack.
Infix Expression: A stack is used to store operators and parentheses during evaluation,
following precedence and associativity rules.
Question 13:
Answer:
A stack can be used to reverse a string by pushing each character of the string onto the stack and
then popping the characters one by one. Since stacks follow the LIFO (Last In, First Out)
principle, popping the characters will give them in reverse order.
Example:
c
Copy code
void reverseString(char str[]) {
Stack stack;
initializeStack(&stack);
int i = 0;
Question 14:
What is the difference between a stack and a queue in terms of data access?
Answer:
The primary difference between a stack and a queue lies in the order in which elements are
accessed:
1. Stack (LIFO):
o Last In First Out (LIFO): The most recently added element is the first to be
removed.
o Operations are performed at one end (top).
2. Queue (FIFO):
o First In First Out (FIFO): The first element added is the first to be removed.
o Operations are performed at both ends (front for dequeue, rear for enqueue).
Example:
Question 15:
Answer:
Stack overflow occurs when the stack exceeds its allocated memory size. It typically happens
when too many elements are pushed onto the stack, or in recursive functions, when the recursion
goes too deep.
Causes:
1. Excessive function calls: Deep recursion without a base case can cause a stack overflow.
2. Too many elements pushed to the stack in a fixed-size stack implementation.
Prevention:
Question 16:
A stack is used to manage function calls in most programming languages, also known as the call
stack. Each time a function is called, a new stack frame is pushed onto the stack, which
contains the function's local variables, return address, and other state information. Once the
function completes execution, the corresponding stack frame is popped, and control is transferred
back to the calling function.
Example: For a recursive function like factorial(n), each recursive call pushes a new frame
onto the stack, and once the base case is reached, the frames are popped as the recursion
unwinds.
Time Complexity: Each function call and return operation takes O(1) time, but deep recursion
may lead to a stack overflow.
Question 17:
Explain how a stack can be used to check for balanced parentheses in an expression.
Answer:
A stack can be used to check if an expression has balanced parentheses by pushing opening
parentheses onto the stack and popping them when a closing parenthesis is encountered. If the
stack is empty when a closing parenthesis is encountered, or if there are any unmatched opening
parentheses left in the stack at the end, the parentheses are unbalanced.
Steps:
Example: For the expression {[()()]}, the stack operations would be:
Push { → stack: {
Push [ → stack: {[
Push ( → stack: {[(
Pop ) → stack: {[
Pop ] → stack: {
Pop { → stack: empty
Answer:
1. The head of the linked list represents the top of the stack.
2. Push operation adds a new node at the head of the list (top of the stack).
3. Pop operation removes the node from the head of the list (top of the stack).
4. Peek operation returns the data from the head node without removing it.
Advantages:
Dynamic size: Unlike an array-based stack, a stack implemented with a linked list does
not have a fixed size.
No overflow as long as memory is available.
Example Code:
c
Copy code
struct StackNode {
int data;
struct StackNode* next;
};
Answer:
A stack and a dynamic array differ in terms of operations, memory allocation, and usage:
1. Stack:
A stack follows the Last In First Out (LIFO) principle, where elements are
o
added and removed from the same end (top).
o Operations are typically Push and Pop.
o Memory is allocated in a linear fashion, and the size of the stack may be fixed or
dynamic.
2. Dynamic Array:
o A dynamic array allows random access to elements, meaning elements can be
accessed by index.
o It can grow in size dynamically (based on the number of elements), but its
memory is contiguous.
o Operations include Insert, Delete, and Access by index.
Example:
Question 20:
Answer:
In Depth-First Search (DFS), a stack is used to explore nodes of a graph or tree in a depthward
motion, meaning it explores as far down a branch as possible before backtracking.
1. The algorithm starts at the root or a source node and pushes it onto the stack.
2. It explores each node by popping from the stack, visiting its neighbors, and pushing them
onto the stack.
3. This continues until all nodes have been visited or the stack is empty.
Example: For a graph with nodes A, B, and C, the DFS traversal using a stack may go:
Time Complexity: O(V + E) where V is the number of vertices and E is the number of edges.
Question 21:
Answer:
1. Dynamic Size: Unlike an array-based stack, a linked list-based stack doesn't have a fixed
size and can grow or shrink dynamically as long as there is memory available.
2. No Overflow: Since memory is allocated dynamically for each element (node), there is
no risk of stack overflow due to fixed size, unlike an array where memory is pre-
allocated.
3. Efficient Memory Usage: Memory is allocated only when a new node is pushed onto the
stack, ensuring better memory usage for sparse stacks.
Example: The stack size increases or decreases with each push and pop operation, and there’s
no need to worry about re-sizing or memory overflow.
Question 22:
Answer:
The time complexity of accessing an element in a stack is O(1), as it involves directly accessing
the element at the top of the stack without having to traverse the stack.
Peek/Top operation: Accesses the top element of the stack in constant time.
int peek() {
if (top == -1) {
printf("Stack is empty\n");
return -1; // No element in the stack
}
return stack[top]; // Return the top element
}
Question 23:
Answer:
A stack can be used to reverse a number by pushing each digit of the number onto the stack, and
then popping the digits to form the reversed number.
Steps:
Question 24:
What is stack resizing, and how can it be handled in an array-based stack implementation?
Answer:
Stack resizing refers to the process of resizing the stack when the current capacity is reached. In
an array-based stack, the size of the stack is typically fixed. When the stack becomes full, it
needs to be resized by reallocating memory.
When the stack is full (i.e., the top index is equal to the maximum size of the array), the
array is resized to a larger size, often doubling the current size.
Similarly, when the stack size shrinks due to many pop operations, it can be resized to a
smaller size.
Example:
void resizeStack() {
int newSize = top * 2; // Double the stack size
stack = realloc(stack, newSize * sizeof(int));
}
Time Complexity:
Question 25:
Answer:
The top pointer in a stack keeps track of the index or position of the topmost element in the
stack. It is used to perform operations like push, pop, and peek:
Push: The top pointer is incremented, and the element is added at that position.
Pop: The top pointer is decremented after removing the top element.
Peek: The element at the position indicated by the top pointer is accessed without
modifying the stack.
Initial Value:
Example:
int stack[MAX];
int top = -1; // Empty stack
Push operation: top++ and add the element at stack[top].
Pop operation: Remove the element from stack[top] and then top--.