diff --git a/src/main/java/com/thealgorithms/searches/BinarySearch.java b/src/main/java/com/thealgorithms/searches/BinarySearch.java index ca873fc6eafa..11d2d065536a 100644 --- a/src/main/java/com/thealgorithms/searches/BinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/BinarySearch.java @@ -5,30 +5,38 @@ /** * Binary Search Algorithm Implementation * - *
Binary search is one of the most efficient searching algorithms for finding a target element - * in a SORTED array. It works by repeatedly dividing the search space in half, eliminating half of - * the remaining elements in each step. + *
+ * Binary search is one of the most efficient searching algorithms for finding a + * target element in a SORTED array. It works by repeatedly dividing the search + * space in half, eliminating half of the remaining elements in each step. * - *
IMPORTANT: This algorithm ONLY works correctly if the input array is sorted in ascending - * order. + *
+ * IMPORTANT: This algorithm ONLY works correctly if the input array is sorted + * in ascending order. * - *
Algorithm Overview: 1. Start with the entire array (left = 0, right = array.length - 1) 2. - * Calculate the middle index 3. Compare the middle element with the target: - If middle element - * equals target: Found! Return the index - If middle element is less than target: Search the right - * half - If middle element is greater than target: Search the left half 4. Repeat until element is - * found or search space is exhausted + *
+ * Algorithm Overview: 1. Start with the entire array (left = 0, right = + * array.length - 1) 2. Calculate the middle index 3. Compare the middle element + * with the target: - If middle element equals target: Found! Return the index - + * If middle element is less than target: Search the right half - If middle + * element is greater than target: Search the left half 4. Repeat until element + * is found or search space is exhausted * - *
Performance Analysis: - Best-case time complexity: O(1) - Element found at middle on first - * try - Average-case time complexity: O(log n) - Most common scenario - Worst-case time - * complexity: O(log n) - Element not found or at extreme end - Space complexity: O(1) - Only uses - * a constant amount of extra space + *
+ * Performance Analysis: - Best-case time complexity: O(1) - Element found at + * middle on first try - Average-case time complexity: O(log n) - Most common + * scenario - Worst-case time complexity: O(log n) - Element not found or at + * extreme end - Space complexity: O(1) - Only uses a constant amount of extra + * space * - *
Example Walkthrough: Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] Target: 7 + *
+ * Example Walkthrough: Array: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] Target: 7 * - *
Step 1: left=0, right=9, mid=4, array[4]=9 (9 > 7, search left half) Step 2: left=0, - * right=3, mid=1, array[1]=3 (3 < 7, search right half) Step 3: left=2, right=3, mid=2, - * array[2]=5 (5 < 7, search right half) Step 4: left=3, right=3, mid=3, array[3]=7 (Found! - * Return index 3) + *
+ * Step 1: left=0, right=9, mid=4, array[4]=9 (9 > 7, search left half) Step + * 2: left=0, right=3, mid=1, array[1]=3 (3 < 7, search right half) Step 3: + * left=2, right=3, mid=2, array[2]=5 (5 < 7, search right half) Step 4: + * left=3, right=3, mid=3, array[3]=7 (Found! Return index 3) * * @author Varun Upadhyay (https://github.com/varunu28) * @author Podshivalov Nikita (https://github.com/nikitap492) @@ -37,98 +45,114 @@ */ class BinarySearch implements SearchAlgorithm { - /** - * Generic method to perform binary search on any comparable type. This is the main entry point - * for binary search operations. - * - *
Example Usage: - *
- * Integer[] numbers = {1, 3, 5, 7, 9, 11};
- * int result = new BinarySearch().find(numbers, 7);
- * // result will be 3 (index of element 7)
- *
- * int notFound = new BinarySearch().find(numbers, 4);
- * // notFound will be -1 (element 4 does not exist)
- *
- *
- * @param + * Example Usage: + * + *
+ * Integer[] numbers = { 1, 3, 5, 7, 9, 11 };
+ * int result = new BinarySearch().find(numbers, 7);
+ * // result will be 3 (index of element 7)
+ *
+ * int notFound = new BinarySearch().find(numbers, 4);
+ * // notFound will be -1 (element 4 does not exist)
+ *
+ *
+ * @param Edge Cases: + *
How it works: - *
Time Complexity: O(log n) because we halve the search space each time.
- * Space Complexity: O(log n) due to recursive call stack.
- *
- * @param
+ * How it works:
+ *
+ * Time Complexity: O(log n) because we halve the search space each time. Space
+ * Complexity: O(log n) due to recursive call stack.
+ *
+ * @param
+ * Example (Simple):
+ * Explanation (Easy):
* Time Complexity:
+ *
+ *
+ *
+ * Input: arr = [2, 4, 6, 8, 10], key = 8
+ * Output: 3
+ *
+ *
+ * Instead of checking every element one by one, Jump Search skips elements
+ * by jumping ahead fixed steps (√n). Once it finds a range where the element
+ * might exist, it performs a linear search in that smaller block.
+ *
+ *
* - Best-case: O(1) - element found at first position
* - Average: O(√n) - optimal block size reduces jumps
diff --git a/src/main/java/com/thealgorithms/stacks/StackUsingLinkedList.java b/src/main/java/com/thealgorithms/stacks/StackUsingLinkedList.java
new file mode 100644
index 000000000000..88197231795c
--- /dev/null
+++ b/src/main/java/com/thealgorithms/stacks/StackUsingLinkedList.java
@@ -0,0 +1,70 @@
+package com.thealgorithms.stacks;
+
+/**
+ * A class that implements a Stack using a singly linked list.
+ * Supports basic operations like push, pop, peek, and isEmpty.
+ *
+ * Reference: https://www.geeksforgeeks.org/stack-using-linked-list/
+ */
+public class StackUsingLinkedList {
+
+ /**
+ * Node class representing each element in the stack
+ */
+ private static class Node {
+ int data;
+ Node next;
+
+ Node(int data) {
+ this.data = data;
+ }
+ }
+
+ private Node top;
+
+ /**
+ * Push an element onto the stack
+ *
+ * @param value the value to push
+ */
+ public void push(int value) {
+ Node newNode = new Node(value);
+ newNode.next = top;
+ top = newNode;
+ }
+
+ /**
+ * Remove and return the top element of the stack
+ *
+ * @return top element
+ */
+ public int pop() {
+ if (top == null) {
+ throw new RuntimeException("Stack is empty");
+ }
+ int value = top.data;
+ top = top.next;
+ return value;
+ }
+
+ /**
+ * Return the top element without removing it
+ *
+ * @return top element
+ */
+ public int peek() {
+ if (top == null) {
+ throw new RuntimeException("Stack is empty");
+ }
+ return top.data;
+ }
+
+ /**
+ * Check if the stack is empty
+ *
+ * @return true if empty, false otherwise
+ */
+ public boolean isEmpty() {
+ return top == null;
+ }
+}
diff --git a/src/test/java/com/thealgorithms/stacks/StackUsingLinkedListTest.java b/src/test/java/com/thealgorithms/stacks/StackUsingLinkedListTest.java
new file mode 100644
index 000000000000..c06604fa95fd
--- /dev/null
+++ b/src/test/java/com/thealgorithms/stacks/StackUsingLinkedListTest.java
@@ -0,0 +1,75 @@
+package com.thealgorithms.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;
+
+/**
+ * Test class for StackUsingLinkedList.
+ *
+ * This class contains unit tests to verify the correctness
+ * of stack operations such as push, pop, peek, and isEmpty.
+ *
+ * Reference: https://www.geeksforgeeks.org/stack-using-linked-list/
+ */
+class StackUsingLinkedListTest {
+
+ /**
+ * Test push and pop operations
+ */
+ @Test
+ void testPushAndPop() {
+ StackUsingLinkedList stack = new StackUsingLinkedList();
+ stack.push(10);
+ stack.push(20);
+
+ assertEquals(20, stack.pop());
+ assertEquals(10, stack.pop());
+ }
+
+ /**
+ * Test peek operation
+ */
+ @Test
+ void testPeek() {
+ StackUsingLinkedList stack = new StackUsingLinkedList();
+ stack.push(5);
+
+ assertEquals(5, stack.peek());
+ }
+
+ /**
+ * Test isEmpty method
+ */
+ @Test
+ void testIsEmpty() {
+ StackUsingLinkedList stack = new StackUsingLinkedList();
+
+ assertTrue(stack.isEmpty());
+ stack.push(1);
+ assertFalse(stack.isEmpty());
+ }
+
+ /**
+ * Test pop on empty stack (edge case)
+ */
+ @Test
+ void testPopOnEmptyStack() {
+ StackUsingLinkedList stack = new StackUsingLinkedList();
+
+ assertThrows(RuntimeException.class, stack::pop);
+ }
+
+ /**
+ * Test peek on empty stack (edge case)
+ */
+ @Test
+ void testPeekOnEmptyStack() {
+ StackUsingLinkedList stack = new StackUsingLinkedList();
+
+ assertThrows(RuntimeException.class, stack::peek);
+ }
+}