From 809c5758be65dbd752579a275185dbbe2171e167 Mon Sep 17 00:00:00 2001 From: DevAta515 Date: Sun, 26 Oct 2025 13:33:14 +0530 Subject: [PATCH] added stack algorithms in java --- Stack.java | 423 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 423 insertions(+) create mode 100644 Stack.java diff --git a/Stack.java b/Stack.java new file mode 100644 index 0000000..f588023 --- /dev/null +++ b/Stack.java @@ -0,0 +1,423 @@ +import java.util.Arrays; +import java.util.EmptyStackException; + +/** + * A comprehensive implementation of Stack data structure with various algorithms. + * This implementation uses an array-based approach with dynamic resizing. + * + * @param the type of elements in this stack + * @author SUDIPTO-2005 + */ +public class Stack { + private static final int DEFAULT_CAPACITY = 10; + private Object[] elements; + private int size; + + /** + * Constructs an empty stack with default capacity. + */ + public Stack() { + this.elements = new Object[DEFAULT_CAPACITY]; + this.size = 0; + } + + /** + * Constructs an empty stack with specified initial capacity. + * + * @param initialCapacity the initial capacity of the stack + * @throws IllegalArgumentException if initialCapacity is negative + */ + public Stack(int initialCapacity) { + if (initialCapacity < 0) { + throw new IllegalArgumentException("Illegal Capacity: " + initialCapacity); + } + this.elements = new Object[initialCapacity]; + this.size = 0; + } + + /** + * Pushes an element onto the top of the stack. + * Time Complexity: O(1) amortized + * + * @param item the element to be pushed + */ + public void push(T item) { + ensureCapacity(); + elements[size++] = item; + } + + /** + * Removes and returns the top element of the stack. + * Time Complexity: O(1) + * + * @return the top element + * @throws EmptyStackException if stack is empty + */ + @SuppressWarnings("unchecked") + public T pop() { + if (isEmpty()) { + throw new EmptyStackException(); + } + T item = (T) elements[--size]; + elements[size] = null; // Help garbage collection + return item; + } + + /** + * Returns the top element without removing it. + * Time Complexity: O(1) + * + * @return the top element + * @throws EmptyStackException if stack is empty + */ + @SuppressWarnings("unchecked") + public T peek() { + if (isEmpty()) { + throw new EmptyStackException(); + } + return (T) elements[size - 1]; + } + + /** + * Checks if the stack is empty. + * Time Complexity: O(1) + * + * @return true if stack is empty, false otherwise + */ + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns the number of elements in the stack. + * Time Complexity: O(1) + * + * @return the size of the stack + */ + public int size() { + return size; + } + + /** + * Removes all elements from the stack. + * Time Complexity: O(n) + */ + public void clear() { + for (int i = 0; i < size; i++) { + elements[i] = null; + } + size = 0; + } + + /** + * Searches for an element in the stack and returns its position from the top. + * The top element is at position 1, the next element at position 2, etc. + * Time Complexity: O(n) + * + * @param item the element to search for + * @return the position from top (1-based), or -1 if not found + */ + public int search(T item) { + for (int i = size - 1; i >= 0; i--) { + if (elements[i] == null ? item == null : elements[i].equals(item)) { + return size - i; + } + } + return -1; + } + + /** + * Returns the element at the specified position from the bottom (0-based index). + * Time Complexity: O(1) + * + * @param index the index from bottom + * @return the element at specified index + * @throws IndexOutOfBoundsException if index is invalid + */ + @SuppressWarnings("unchecked") + public T get(int index) { + if (index < 0 || index >= size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + return (T) elements[index]; + } + + /** + * Reverses the elements in the stack. + * Time Complexity: O(n) + */ + public void reverse() { + int left = 0; + int right = size - 1; + while (left < right) { + Object temp = elements[left]; + elements[left] = elements[right]; + elements[right] = temp; + left++; + right--; + } + } + + /** + * Returns a copy of this stack. + * Time Complexity: O(n) + * + * @return a new stack with same elements + */ + @SuppressWarnings("unchecked") + public Stack clone() { + Stack cloned = new Stack<>(size); + cloned.size = this.size; + cloned.elements = Arrays.copyOf(this.elements, this.size); + return cloned; + } + + /** + * Checks if the stack contains the specified element. + * Time Complexity: O(n) + * + * @param item the element to check + * @return true if element exists, false otherwise + */ + public boolean contains(T item) { + return search(item) != -1; + } + + /** + * Returns the minimum element in the stack (for Comparable types). + * Time Complexity: O(n) + * + * @return the minimum element + * @throws EmptyStackException if stack is empty + * @throws ClassCastException if elements are not Comparable + */ + @SuppressWarnings("unchecked") + public T min() { + if (isEmpty()) { + throw new EmptyStackException(); + } + Comparable min = (Comparable) elements[0]; + for (int i = 1; i < size; i++) { + if (min.compareTo((T) elements[i]) > 0) { + min = (Comparable) elements[i]; + } + } + return (T) min; + } + + /** + * Returns the maximum element in the stack (for Comparable types). + * Time Complexity: O(n) + * + * @return the maximum element + * @throws EmptyStackException if stack is empty + * @throws ClassCastException if elements are not Comparable + */ + @SuppressWarnings("unchecked") + public T max() { + if (isEmpty()) { + throw new EmptyStackException(); + } + Comparable max = (Comparable) elements[0]; + for (int i = 1; i < size; i++) { + if (max.compareTo((T) elements[i]) < 0) { + max = (Comparable) elements[i]; + } + } + return (T) max; + } + + /** + * Sorts the stack in ascending order (for Comparable types). + * Time Complexity: O(n²) + */ + @SuppressWarnings("unchecked") + public void sort() { + if (size <= 1) return; + + // Bubble sort implementation + for (int i = 0; i < size - 1; i++) { + for (int j = 0; j < size - i - 1; j++) { + Comparable current = (Comparable) elements[j]; + if (current.compareTo((T) elements[j + 1]) > 0) { + Object temp = elements[j]; + elements[j] = elements[j + 1]; + elements[j + 1] = temp; + } + } + } + } + + /** + * Removes all occurrences of the specified element. + * Time Complexity: O(n) + * + * @param item the element to remove + * @return the number of elements removed + */ + public int removeAll(T item) { + int writeIndex = 0; + int removedCount = 0; + + for (int readIndex = 0; readIndex < size; readIndex++) { + if (elements[readIndex] == null ? item != null : !elements[readIndex].equals(item)) { + elements[writeIndex++] = elements[readIndex]; + } else { + removedCount++; + } + } + + // Clear remaining references + for (int i = writeIndex; i < size; i++) { + elements[i] = null; + } + + size = writeIndex; + return removedCount; + } + + /** + * Returns an array containing all elements in the stack (bottom to top). + * Time Complexity: O(n) + * + * @return array of stack elements + */ + public Object[] toArray() { + return Arrays.copyOf(elements, size); + } + + /** + * Merges another stack into this stack. + * Time Complexity: O(n) where n is size of other stack + * + * @param other the stack to merge + */ + @SuppressWarnings("unchecked") + public void merge(Stack other) { + if (other == null || other.isEmpty()) return; + + ensureCapacity(size + other.size); + for (int i = 0; i < other.size; i++) { + elements[size++] = other.elements[i]; + } + } + + /** + * Rotates the stack by n positions to the right. + * Time Complexity: O(n) + * + * @param positions number of positions to rotate + */ + public void rotate(int positions) { + if (size <= 1) return; + + positions = positions % size; + if (positions < 0) positions += size; + if (positions == 0) return; + + reverse(0, size - 1); + reverse(0, positions - 1); + reverse(positions, size - 1); + } + + /** + * Helper method to reverse elements in a range. + * + * @param start start index + * @param end end index + */ + private void reverse(int start, int end) { + while (start < end) { + Object temp = elements[start]; + elements[start] = elements[end]; + elements[end] = temp; + start++; + end--; + } + } + + /** + * Returns string representation of the stack. + * Format: [bottom, ..., top] + * + * @return string representation + */ + @Override + public String toString() { + if (isEmpty()) { + return "[]"; + } + + StringBuilder sb = new StringBuilder("["); + for (int i = 0; i < size; i++) { + sb.append(elements[i]); + if (i < size - 1) { + sb.append(", "); + } + } + sb.append("]"); + return sb.toString(); + } + + /** + * Ensures capacity for new elements. Doubles capacity when needed. + */ + private void ensureCapacity() { + ensureCapacity(size + 1); + } + + /** + * Ensures capacity for specified number of elements. + * + * @param minCapacity minimum required capacity + */ + private void ensureCapacity(int minCapacity) { + if (minCapacity > elements.length) { + int newCapacity = Math.max(elements.length * 2, minCapacity); + elements = Arrays.copyOf(elements, newCapacity); + } + } + + /** + * Main method demonstrating stack operations. + */ + public static void main(String[] args) { + // Example usage + Stack stack = new Stack<>(); + + // Push elements + System.out.println("Pushing elements: 10, 20, 30, 40, 50"); + stack.push(10); + stack.push(20); + stack.push(30); + stack.push(40); + stack.push(50); + System.out.println("Stack: " + stack); + + // Peek + System.out.println("Top element (peek): " + stack.peek()); + + // Pop + System.out.println("Popped: " + stack.pop()); + System.out.println("Stack after pop: " + stack); + + // Search + System.out.println("Position of 20 from top: " + stack.search(20)); + + // Size and isEmpty + System.out.println("Size: " + stack.size()); + System.out.println("Is empty: " + stack.isEmpty()); + + // Min and Max + System.out.println("Min element: " + stack.min()); + System.out.println("Max element: " + stack.max()); + + // Reverse + stack.reverse(); + System.out.println("Stack after reverse: " + stack); + + // Sort + stack.sort(); + System.out.println("Stack after sort: " + stack); + } +} \ No newline at end of file