diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f2f8dd9ffdea..41593eddb27d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,27 +5,31 @@ NOTE: *We DO NOT add leetcode problems. They are just applications of basic prin ### Did you find a bug? **Ensure the bug was not already reported** by searching on GitHub under [Project Issues](https://github.com/TheAlgorithms/Java/issues). - - If it is mentioned in the issues and you want to fix it, [fork](https://github.com/TheAlgorithms/Java/fork) the repository and submit your implementation in a pull request. The project maintainers will evaluate it. - - If the bug is **NOT** mentioned in the issues, [open a new issue](https://github.com/TheAlgorithms/Java/issues/new). Be sure to include a **title**, a clear **description** and a **test case** demonstrating the expected behavior that is not occurring. + +* If it is mentioned in the issues and you want to fix it, [fork](https://github.com/TheAlgorithms/Java/fork) the repository and submit your implementation in a pull request. The project maintainers will evaluate it. +* If the bug is **NOT** mentioned in the issues, [open a new issue](https://github.com/TheAlgorithms/Java/issues/new). Be sure to include a **title**, a clear **description** and a **test case** demonstrating the expected behavior that is not occurring. NOTE: *Please avoid opening issues asking to be "assigned" to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and project maintainers will evaluate it.* ### Do you want to contribute to the documentation? - - [Fork](https://github.com/TheAlgorithms/Java/fork) the repository and make necessary changes. - - Create a pull request. - - It will be put under review for approval. - - If approved, the requested changes will be merged to the repository. + +* [Fork](https://github.com/TheAlgorithms/Java/fork) the repository and make necessary changes. +* Create a pull request. +* It will be put under review for approval. +* If approved, the requested changes will be merged to the repository. ### Do you want to add a new feature? -- [Open a new issue](https://github.com/TheAlgorithms/Java/issues/new). -- Be sure to include a **title**, a clear **description** and a **test case** demonstrating the new feature you want to add to the project. +* [Open a new issue](https://github.com/TheAlgorithms/Java/issues/new). +* Be sure to include a **title**, a clear **description** and a **test case** demonstrating the new feature you want to add to the project. + ### Do you have questions about the source code? -- Ask any question about how to use the repository in the [TheAlgorithms room in GITTER](https://gitter.im/TheAlgorithms/community?source=orgpage#) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new) +* Ask any question about how to use the repository in \[TheAlgorithms Discord server](https://discord.gg/c7MnfGFGa6) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new) + +:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada: -:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada: \ No newline at end of file diff --git a/jh bihkwdslj b/jh bihkwdslj new file mode 100644 index 000000000000..ce3ccbb6e7eb --- /dev/null +++ b/jh bihkwdslj @@ -0,0 +1,105 @@ + + SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS + + Commands marked with * may be preceded by a number, _N. + Notes in parentheses indicate the behavior if _N is given. + A key preceded by a caret indicates the Ctrl key; thus ^K is ctrl-K. + + h H Display this help. + q :q Q :Q ZZ Exit. + --------------------------------------------------------------------------- + + MMOOVVIINNGG + + e ^E j ^N CR * Forward one line (or _N lines). + y ^Y k ^K ^P * Backward one line (or _N lines). + ESC-j * Forward one file line (or _N file lines). + ESC-k * Backward one file line (or _N file lines). + f ^F ^V SPACE * Forward one window (or _N lines). + b ^B ESC-v * Backward one window (or _N lines). + z * Forward one window (and set window to _N). + w * Backward one window (and set window to _N). + ESC-SPACE * Forward one window, but don't stop at end-of-file. + ESC-b * Backward one window, but don't stop at beginning-of-file. + d ^D * Forward one half-window (and set half-window to _N). + u ^U * Backward one half-window (and set half-window to _N). + ESC-) RightArrow * Right one half screen width (or _N positions). + ESC-( LeftArrow * Left one half screen width (or _N positions). + ESC-} ^RightArrow Right to last column displayed. + ESC-{ ^LeftArrow Left to first column. + F Forward forever; like "tail -f". + ESC-F Like F but stop when search pattern is found. + r ^R ^L Repaint screen. + R Repaint screen, discarding buffered input. + --------------------------------------------------- + Default "window" is the screen height. + Default "half-window" is half of the screen height. + --------------------------------------------------------------------------- + + SSEEAARRCCHHIINNGG + + /_p_a_t_t_e_r_n * Search forward for (_N-th) matching line. + ?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line. + n * Repeat previous search (for _N-th occurrence). + N * Repeat previous search in reverse direction. + ESC-n * Repeat previous search, spanning files. + ESC-N * Repeat previous search, reverse dir. & spanning files. + ^O^N ^On * Search forward for (_N-th) OSC8 hyperlink. + ^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink. + ^O^L ^Ol Jump to the currently selected OSC8 hyperlink. + ESC-u Undo (toggle) search highlighting. + ESC-U Clear search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines. + --------------------------------------------------- + Search is case-sensitive unless changed with -i or -I. + A search pattern may begin with one or more of: + ^N or ! Search for NON-matching lines. + ^E or * Search multiple files (pass thru END OF FILE). + ^F or @ Start search at FIRST file (for /) or last file (for ?). + ^K Highlight matches, but don't move (KEEP position). + ^R Don't use REGULAR EXPRESSIONS. + ^S _n Search for match in _n-th parenthesized subpattern. + ^W WRAP search if no match found. + ^L Enter next character literally into pattern. + --------------------------------------------------------------------------- + + JJUUMMPPIINNGG + + g < ESC-< * Go to first line in file (or line _N). + G > ESC-> * Go to last line in file (or line _N). + p % * Go to beginning of file (or _N percent into file). + t * Go to the (_N-th) next tag. + T * Go to the (_N-th) previous tag. + { ( [ * Find close bracket } ) ]. + } ) ] * Find open bracket { ( [. + ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>. + ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>. + --------------------------------------------------- + Each "find close bracket" command goes forward to the close bracket + matching the (_N-th) open bracket in the top line. + Each "find open bracket" command goes backward to the open bracket + matching the (_N-th) close bracket in the bottom line. + + m_<_l_e_t_t_e_r_> Mark the current top line with . + M_<_l_e_t_t_e_r_> Mark the current bottom line with . + '_<_l_e_t_t_e_r_> Go to a previously marked position. + '' Go to the previous position. + ^X^X Same as '. + ESC-m_<_l_e_t_t_e_r_> Clear a mark. + --------------------------------------------------- + A mark is any upper-case or lower-case letter. + Certain marks are predefined: + ^ means beginning of the file + $ means end of the file + --------------------------------------------------------------------------- + + CCHHAANNGGIINNGG FFIILLEESS + + :e [_f_i_l_e] Examine a new file. + ^X^V Same as :e. + :n * Examine the (_N-th) next file from the command line. + :p * Examine the (_N-th) previous file from the command line. + :x * Examine the first (or _N-th) file from the command line. + ^O^O Open the currently selected OSC8 hyperlink. + :d Delete the current file from the command line list. + = ^G :f Print current file name. diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedList.java b/src/main/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedList.java new file mode 100644 index 000000000000..c2b01d9885a6 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedList.java @@ -0,0 +1,213 @@ +package com.thealgorithms.datastructures.stacks; + +/** + * A generic stack implementation using a singly linked list. + * This implementation provides O(1) time complexity for push, pop, and peek operations. + * + * @param the type of elements held in this stack + * @author Your Name + */ +public class StackUsingLinkedList { + + /** + * Inner class representing a node in the linked list. + */ + private static class Node { + T data; + Node next; + + /** + * Constructs a new node with the given data. + * + * @param data the data to store in this node + */ + Node(T data) { + this.data = data; + this.next = null; + } + } + + private Node top; + private int size; + + /** + * Constructs an empty stack. + */ + public StackUsingLinkedList() { + this.top = null; + this.size = 0; + } + + /** + * Pushes an element onto the top of this stack. + * Time Complexity: O(1) + * + * @param data the element to be pushed onto this stack + */ + public void push(T data) { + Node newNode = new Node<>(data); + newNode.next = top; + top = newNode; + size++; + } + + /** + * Removes and returns the element at the top of this stack. + * Time Complexity: O(1) + * + * @return the element at the top of this stack + * @throws IllegalStateException if this stack is empty + */ + public T pop() { + if (isEmpty()) { + throw new IllegalStateException("Stack is empty. Cannot pop element."); + } + T data = top.data; + top = top.next; + size--; + return data; + } + + /** + * Returns the element at the top of this stack without removing it. + * Time Complexity: O(1) + * + * @return the element at the top of this stack + * @throws IllegalStateException if this stack is empty + */ + public T peek() { + if (isEmpty()) { + throw new IllegalStateException("Stack is empty. Cannot peek element."); + } + return top.data; + } + + /** + * Checks if this stack is empty. + * Time Complexity: O(1) + * + * @return {@code true} if this stack contains no elements, {@code false} otherwise + */ + public boolean isEmpty() { + return top == null; + } + + /** + * Returns the number of elements in this stack. + * Time Complexity: O(1) + * + * @return the number of elements in this stack + */ + public int size() { + return size; + } + + /** + * Removes all elements from this stack. + * Time Complexity: O(1) + */ + public void clear() { + top = null; + size = 0; + } + + /** + * Returns a string representation of this stack. + * The string representation consists of a list of the stack's elements + * from top to bottom, enclosed in square brackets ("[]"). + * + * @return a string representation of this stack + */ + @Override + public String toString() { + if (isEmpty()) { + return "[]"; + } + + StringBuilder sb = new StringBuilder("["); + Node current = top; + while (current != null) { + sb.append(current.data); + if (current.next != null) { + sb.append(", "); + } + current = current.next; + } + sb.append("]"); + return sb.toString(); + } + + /** + * Demonstration of the StackUsingLinkedList implementation. + * + * @param args command line arguments (not used) + */ + public static void main(String[] args) { + // Example 1: Stack of Integers + System.out.println("=== Integer Stack Demo ==="); + StackUsingLinkedList intStack = new StackUsingLinkedList<>(); + + // Push elements + intStack.push(10); + intStack.push(20); + intStack.push(30); + intStack.push(40); + System.out.println("Stack after pushing 10, 20, 30, 40: " + intStack); + System.out.println("Size: " + intStack.size()); + + // Peek + System.out.println("Top element (peek): " + intStack.peek()); + + // Pop elements + System.out.println("Popped: " + intStack.pop()); + System.out.println("Popped: " + intStack.pop()); + System.out.println("Stack after popping twice: " + intStack); + System.out.println("Size: " + intStack.size()); + + // Check if empty + System.out.println("Is stack empty? " + intStack.isEmpty()); + + // Pop remaining elements + intStack.pop(); + intStack.pop(); + System.out.println("Is stack empty after popping all? " + intStack.isEmpty()); + + // Example 2: Stack of Strings + System.out.println("\n=== String Stack Demo ==="); + StackUsingLinkedList stringStack = new StackUsingLinkedList<>(); + + stringStack.push("Hello"); + stringStack.push("World"); + stringStack.push("Java"); + System.out.println("Stack: " + stringStack); + System.out.println("Top: " + stringStack.peek()); + System.out.println("Popped: " + stringStack.pop()); + System.out.println("Stack after pop: " + stringStack); + + // Example 3: Exception handling + System.out.println("\n=== Exception Handling Demo ==="); + StackUsingLinkedList emptyStack = new StackUsingLinkedList<>(); + try { + emptyStack.pop(); + } catch (IllegalStateException e) { + System.out.println("Caught exception: " + e.getMessage()); + } + + try { + emptyStack.peek(); + } catch (IllegalStateException e) { + System.out.println("Caught exception: " + e.getMessage()); + } + + // Example 4: Clear operation + System.out.println("\n=== Clear Operation Demo ==="); + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + stack.push(1); + stack.push(2); + stack.push(3); + System.out.println("Stack before clear: " + stack); + stack.clear(); + System.out.println("Stack after clear: " + stack); + System.out.println("Is empty? " + stack.isEmpty()); + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedListTest.java new file mode 100644 index 000000000000..a6f6c8d4de3d --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/stacks/StackUsingLinkedListTest.java @@ -0,0 +1,90 @@ +package com.thealgorithms.datastructures.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class StackUsingLinkedListTest { + @Test + void testPushAndPop() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + stack.push(10); + stack.push(20); + stack.push(30); + assertEquals(30, stack.pop()); + assertEquals(20, stack.pop()); + assertEquals(10, stack.pop()); + } + + @Test + void testPeek() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + stack.push(100); + stack.push(200); + assertEquals(200, stack.peek()); + assertEquals(200, stack.peek()); + assertEquals(2, stack.size()); + } + + @Test + void testIsEmpty() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + assertTrue(stack.isEmpty()); + stack.push(5); + assertFalse(stack.isEmpty()); + stack.pop(); + assertTrue(stack.isEmpty()); + } + + @Test + void testSize() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + assertEquals(0, stack.size()); + stack.push(1); + assertEquals(1, stack.size()); + stack.push(2); + stack.push(3); + assertEquals(3, stack.size()); + stack.pop(); + assertEquals(2, stack.size()); + } + + @Test + void testPopEmptyStack() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + assertThrows(RuntimeException.class, stack::pop); + } + + @Test + void testPeekEmptyStack() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + assertThrows(RuntimeException.class, stack::peek); + } + + @Test + void testMultipleOperations() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + assertTrue(stack.isEmpty()); + stack.push(1); + stack.push(2); + assertEquals(2, stack.pop()); + stack.push(3); + stack.push(4); + assertEquals(4, stack.peek()); + assertEquals(3, stack.size()); + assertFalse(stack.isEmpty()); + } + + @Test + void testSingleElement() { + StackUsingLinkedList stack = new StackUsingLinkedList<>(); + stack.push(42); + assertEquals(42, stack.peek()); + assertEquals(1, stack.size()); + assertEquals(42, stack.pop()); + assertTrue(stack.isEmpty()); + } +} \ No newline at end of file