stacks

from collections import deque class Stack: def __init__(self): self.stack = [] def push(self, item): """Push an item onto the stack.""" self.stack.append(item) def pop(self): """Pop an item from the stack. Returns None if the stack is empty.""" if not self.is_empty(): return self.stack.pop() return None def peek(self): """Peek at the top item of the stack without removing it.""" if not self.is_empty(): return self.stack[-1] return None def is_empty(self): """Check if the stack is empty.""" return len(self.stack) == 0 def size(self): """Return the size of the stack.""" return len(self.stack) def clear(self): """Clear all items in the stack.""" self.stack.clear() def print_stack(self): """Print all elements in the stack.""" print(self.stack) def reverse_stack(stack): """Reverse a stack using recursion.""" if stack.is_empty(): return top = stack.pop() reverse_stack(stack) insert_at_bottom(stack, top) def insert_at_bottom(stack, item): """Helper function to insert an item at the bottom of the stack.""" if stack.is_empty(): stack.push(item) else: top = stack.pop() insert_at_bottom(stack, item) stack.push(top) def is_balanced(expression): """Check if the parentheses in the expression are balanced.""" stack = Stack() for char in expression: if char in '([{': stack.push(char) elif char == ')' and (stack.is_empty() or stack.pop() != '('): return False elif char == ']' and (stack.is_empty() or stack.pop() != '['): return False elif char == '}' and (stack.is_empty() or stack.pop() != '{'): return False return stack.is_empty() def dfs_stack(graph, start): """ Perform DFS traversal of a graph using a stack. :param graph: A dictionary representing the graph (adjacency list). :param start: The starting node for DFS traversal. :return: A list of nodes in the order they were visited. """ visited = set() stack = [start] traversal_order = [] while stack: node = stack.pop() if node not in visited: visited.add(node) traversal_order.append(node) for neighbor in graph[node]: if neighbor not in visited: stack.append(neighbor) return traversal_order def bfs_queue(graph, start): """ Perform BFS traversal of a graph using a queue. :param graph: A dictionary representing the graph (adjacency list). :param start: The starting node for BFS traversal. :return: A list of nodes in the order they were visited. """ visited = set() queue = deque([start]) traversal_order = [] while queue: node = queue.popleft() if node not in visited: visited.add(node) traversal_order.append(node) for neighbor in graph[node]: if neighbor not in visited: queue.append(neighbor) return traversal_order def is_palindrome(s): """ Check if a string is a palindrome using a stack. :param s: The string to check. :return: True if the string is a palindrome, False otherwise. """ stack = [] # Push each character onto the stack for char in s: stack.append(char) # Check if the string is a palindrome by comparing characters for char in s: if char != stack.pop(): return False return True def sort_stack(stack): """ Sort a stack using only another stack for auxiliary storage. :param stack: The stack to be sorted. :return: The sorted stack. """ auxiliary_stack = [] while stack: current = stack.pop() # Move elements from auxiliary stack back to stack if they are greater than current while auxiliary_stack and auxiliary_stack[-1] > current: stack.append(auxiliary_stack.pop()) # Push the current element to the auxiliary stack auxiliary_stack.append(current) # Move all elements back to the original stack while auxiliary_stack: stack.append(auxiliary_stack.pop()) return stack class MinStack: def __init__(self): """ Initialize the stack and the auxiliary stack to keep track of minimum elements. """ self.stack = [] self.min_stack = [] def push(self, x): """ Push an element onto the stack. :param x: The element to be pushed onto the stack. """ self.stack.append(x) # Push the minimum element onto the min_stack if not self.min_stack or x

Mar 22, 2025 - 05:06
 0
stacks
from collections import deque

class Stack:
    def __init__(self):
        self.stack = []

    def push(self, item):
        """Push an item onto the stack."""
        self.stack.append(item)

    def pop(self):
        """Pop an item from the stack. Returns None if the stack is empty."""
        if not self.is_empty():
            return self.stack.pop()
        return None

    def peek(self):
        """Peek at the top item of the stack without removing it."""
        if not self.is_empty():
            return self.stack[-1]
        return None

    def is_empty(self):
        """Check if the stack is empty."""
        return len(self.stack) == 0

    def size(self):
        """Return the size of the stack."""
        return len(self.stack)

    def clear(self):
        """Clear all items in the stack."""
        self.stack.clear()

    def print_stack(self):
        """Print all elements in the stack."""
        print(self.stack)


def reverse_stack(stack):
    """Reverse a stack using recursion."""
    if stack.is_empty():
        return
    top = stack.pop()
    reverse_stack(stack)
    insert_at_bottom(stack, top)

def insert_at_bottom(stack, item):
    """Helper function to insert an item at the bottom of the stack."""
    if stack.is_empty():
        stack.push(item)
    else:
        top = stack.pop()
        insert_at_bottom(stack, item)
        stack.push(top)


def is_balanced(expression):
    """Check if the parentheses in the expression are balanced."""
    stack = Stack()
    for char in expression:
        if char in '([{':
            stack.push(char)
        elif char == ')' and (stack.is_empty() or stack.pop() != '('):
            return False
        elif char == ']' and (stack.is_empty() or stack.pop() != '['):
            return False
        elif char == '}' and (stack.is_empty() or stack.pop() != '{'):
            return False
    return stack.is_empty()


def dfs_stack(graph, start):
    """
    Perform DFS traversal of a graph using a stack.
    :param graph: A dictionary representing the graph (adjacency list).
    :param start: The starting node for DFS traversal.
    :return: A list of nodes in the order they were visited.
    """
    visited = set()
    stack = [start]
    traversal_order = []

    while stack:
        node = stack.pop()
        if node not in visited:
            visited.add(node)
            traversal_order.append(node)
            for neighbor in graph[node]:
                if neighbor not in visited:
                    stack.append(neighbor)

    return traversal_order


def bfs_queue(graph, start):
    """
    Perform BFS traversal of a graph using a queue.
    :param graph: A dictionary representing the graph (adjacency list).
    :param start: The starting node for BFS traversal.
    :return: A list of nodes in the order they were visited.
    """
    visited = set()
    queue = deque([start])
    traversal_order = []

    while queue:
        node = queue.popleft()
        if node not in visited:
            visited.add(node)
            traversal_order.append(node)
            for neighbor in graph[node]:
                if neighbor not in visited:
                    queue.append(neighbor)

    return traversal_order


def is_palindrome(s):
    """
    Check if a string is a palindrome using a stack.
    :param s: The string to check.
    :return: True if the string is a palindrome, False otherwise.
    """
    stack = []
    # Push each character onto the stack
    for char in s:
        stack.append(char)

    # Check if the string is a palindrome by comparing characters
    for char in s:
        if char != stack.pop():
            return False
    return True


def sort_stack(stack):
    """
    Sort a stack using only another stack for auxiliary storage.
    :param stack: The stack to be sorted.
    :return: The sorted stack.
    """
    auxiliary_stack = []

    while stack:
        current = stack.pop()

        # Move elements from auxiliary stack back to stack if they are greater than current
        while auxiliary_stack and auxiliary_stack[-1] > current:
            stack.append(auxiliary_stack.pop())

        # Push the current element to the auxiliary stack
        auxiliary_stack.append(current)

    # Move all elements back to the original stack
    while auxiliary_stack:
        stack.append(auxiliary_stack.pop())

    return stack


class MinStack:
    def __init__(self):
        """
        Initialize the stack and the auxiliary stack to keep track of minimum elements.
        """
        self.stack = []
        self.min_stack = []

    def push(self, x):
        """
        Push an element onto the stack.
        :param x: The element to be pushed onto the stack.
        """
        self.stack.append(x)
        # Push the minimum element onto the min_stack
        if not self.min_stack or x <= self.min_stack[-1]:
            self.min_stack.append(x)

    def pop(self):
        """
        Pop the top element from the stack.
        :return: The popped element.
        """
        if self.stack:
            popped_value = self.stack.pop()
            if popped_value == self.min_stack[-1]:
                self.min_stack.pop()
            return popped_value
        return None

    def top(self):
        """
        Get the top element of the stack.
        :return: The top element of the stack.
        """
        return self.stack[-1] if self.stack else None

    def get_min(self):
        """
        Retrieve the minimum element in constant time.
        :return: The minimum element in the stack.
        """
        return self.min_stack[-1] if self.min_stack else None


# Example Use Cases

# 1. Test the Stack class
stack = Stack()
stack.push(10)
stack.push(20)
stack.push(30)
print("Stack operations:")
print(stack.peek())  # Output: 30
print(stack.pop())   # Output: 30
print(stack.size())  # Output: 2
stack.print_stack()  # Output: [10, 20]

# 2. Test DFS
graph = {
    'A': ['B', 'C'],
    'B': ['A', 'D', 'E'],
    'C': ['A', 'F'],
    'D': ['B'],
    'E': ['B', 'F'],
    'F': ['C', 'E']
}
print("\nDFS traversal:", dfs_stack(graph, 'A'))  # Output: ['A', 'C', 'F', 'E', 'B', 'D']

# 3. Test BFS
print("\nBFS traversal:", bfs_queue(graph, 'A'))  # Output: ['A', 'B', 'C', 'D', 'E', 'F']

# 4. Test Palindrome Check
print("\nIs 'racecar' a palindrome?", is_palindrome('racecar'))  # Output: True
print("Is 'hello' a palindrome?", is_palindrome('hello'))  # Output: False

# 5. Test Reversing a Stack
print("\nReversing stack:")
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
reverse_stack(stack)
stack.print_stack()  # Output: [3, 2, 1]

# 6. Test Balanced Parentheses
expression = "{[()()]}"
print("\nIs the expression balanced?", is_balanced(expression))  # Output: True
expression = "{[(])}"
print("Is the expression balanced?", is_balanced(expression))  # Output: False

# 7. Test Sorting a Stack
stack = [5, 2, 9, 1, 5, 6]
print("\nSorted stack:", sort_stack(stack))  # Output: [1, 2, 5, 5, 6, 9]

# 8. Test MinStack
min_stack = MinStack()
min_stack.push(3)
min_stack.push(4)
min_stack.push(2)
min_stack.push(5)
print("\nMinStack get_min:", min_stack.get_min())  # Output: 2
min_stack.pop()
print("MinStack get_min after pop:", min_stack.get_min())  # Output: 2
min_stack.pop()
print("MinStack get_min after pop:", min_stack.get_min())  # Output: 3