diff --git a/algorithms-miscellaneous-1/README.md b/algorithms-miscellaneous-1/README.md
index 6a25f8cac8..25e2733538 100644
--- a/algorithms-miscellaneous-1/README.md
+++ b/algorithms-miscellaneous-1/README.md
@@ -7,8 +7,6 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
- [Validating Input With Finite Automata in Java](https://www.baeldung.com/java-finite-automata)
- [Example of Hill Climbing Algorithm](https://www.baeldung.com/java-hill-climbing-algorithm)
-- [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search)
-- [Binary Search Algorithm in Java](https://www.baeldung.com/java-binary-search)
- [Introduction to Minimax Algorithm](https://www.baeldung.com/java-minimax-algorithm)
- [How to Calculate Levenshtein Distance in Java?](https://www.baeldung.com/java-levenshtein-distance)
- [How to Find the Kth Largest Element in Java](https://www.baeldung.com/java-kth-largest-element)
diff --git a/algorithms-miscellaneous-3/README.md b/algorithms-miscellaneous-3/README.md
index 93426b3e0d..23a10258a3 100644
--- a/algorithms-miscellaneous-3/README.md
+++ b/algorithms-miscellaneous-3/README.md
@@ -14,8 +14,6 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
- [A Guide to the Folding Technique in Java](https://www.baeldung.com/folding-hashing-technique)
- [Creating a Triangle with for Loops in Java](https://www.baeldung.com/java-print-triangle)
- [Efficient Word Frequency Calculator in Java](https://www.baeldung.com/java-word-frequency)
-- [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-search)
- [The K-Means Clustering Algorithm in Java](https://www.baeldung.com/java-k-means-clustering-algorithm)
- [Creating a Custom Annotation in Java](https://www.baeldung.com/java-custom-annotation)
-- [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search)
- More articles: [[<-- prev]](/algorithms-miscellaneous-2) [[next -->]](/algorithms-miscellaneous-4)
diff --git a/algorithms-miscellaneous-4/README.md b/algorithms-miscellaneous-4/README.md
index df2eafb733..dc46007f66 100644
--- a/algorithms-miscellaneous-4/README.md
+++ b/algorithms-miscellaneous-4/README.md
@@ -5,7 +5,6 @@ This module contains articles about algorithms. Some classes of algorithms, e.g.
### Relevant articles:
- [Multi-Swarm Optimization Algorithm in Java](https://www.baeldung.com/java-multi-swarm-algorithm)
-- [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms)
- [Check If a String Contains All The Letters of The Alphabet](https://www.baeldung.com/java-string-contains-all-letters)
- [Find the Middle Element of a Linked List](https://www.baeldung.com/java-linked-list-middle-element)
- [Find Substrings That Are Palindromes in Java](https://www.baeldung.com/java-palindrome-substrings)
diff --git a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java b/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java
deleted file mode 100755
index dfe015aad2..0000000000
--- a/algorithms-miscellaneous-4/src/test/java/com/baeldung/algorithms/StringSearchAlgorithmsUnitTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.baeldung.algorithms;
-
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import com.baeldung.algorithms.string.search.StringSearchAlgorithms;
-
-public class StringSearchAlgorithmsUnitTest {
-
-
- @Test
- public void testStringSearchAlgorithms(){
- String text = "This is some nice text.";
- String pattern = "some";
-
- int realPosition = text.indexOf(pattern);
- Assert.assertTrue(realPosition == StringSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
- Assert.assertTrue(realPosition == StringSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
- }
-
-}
diff --git a/algorithms-searching/README.md b/algorithms-searching/README.md
new file mode 100644
index 0000000000..d86c3e3de8
--- /dev/null
+++ b/algorithms-searching/README.md
@@ -0,0 +1,11 @@
+## Algorithms - Searching
+
+This module contains articles about searching algorithms.
+
+### Relevant articles:
+- [Binary Search Algorithm in Java](https://www.baeldung.com/java-binary-search)
+- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search)
+- [Interpolation Search in Java](https://www.baeldung.com/java-interpolation-search)
+- [Breadth-First Search Algorithm in Java](https://www.baeldung.com/java-breadth-first-search)
+- [String Search Algorithms for Large Texts](https://www.baeldung.com/java-full-text-search-algorithms)
+- [Monte Carlo Tree Search for Tic-Tac-Toe Game](https://www.baeldung.com/java-monte-carlo-tree-search)
diff --git a/algorithms-searching/pom.xml b/algorithms-searching/pom.xml
new file mode 100644
index 0000000000..6bd4b0233e
--- /dev/null
+++ b/algorithms-searching/pom.xml
@@ -0,0 +1,37 @@
+
+ 4.0.0
+ algorithms-searching
+ 0.0.1-SNAPSHOT
+ algorithms-searching
+
+
+ com.baeldung
+ parent-modules
+ 1.0.0-SNAPSHOT
+
+
+
+
+ org.assertj
+ assertj-core
+ ${org.assertj.core.version}
+ test
+
+
+
+
+ algorithms-searching
+
+
+ src/main/resources
+ true
+
+
+
+
+
+ 3.9.0
+
+
+
\ No newline at end of file
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java
similarity index 96%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java
index 5b2ac49d4e..82aefe282b 100644
--- a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java
+++ b/algorithms-searching/src/main/java/com/baeldung/algorithms/binarysearch/BinarySearch.java
@@ -1,55 +1,55 @@
-package com.baeldung.algorithms.binarysearch;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-public class BinarySearch {
-
- public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
-
- int index = Integer.MAX_VALUE;
-
- while (low <= high) {
-
- int mid = (low + high) / 2;
-
- if (sortedArray[mid] < key) {
- low = mid + 1;
- } else if (sortedArray[mid] > key) {
- high = mid - 1;
- } else if (sortedArray[mid] == key) {
- index = mid;
- break;
- }
- }
- return index;
- }
-
- public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
-
- int middle = (low + high) / 2;
- if (high < low) {
- return -1;
- }
-
- if (key == sortedArray[middle]) {
- return middle;
- } else if (key < sortedArray[middle]) {
- return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
- } else {
- return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
- }
- }
-
- public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
- int index = Arrays.binarySearch(sortedArray, key);
- return index;
- }
-
- public int runBinarySearchUsingJavaCollections(List sortedList, Integer key) {
- int index = Collections.binarySearch(sortedList, key);
- return index;
- }
-
-}
+package com.baeldung.algorithms.binarysearch;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class BinarySearch {
+
+ public int runBinarySearchIteratively(int[] sortedArray, int key, int low, int high) {
+
+ int index = Integer.MAX_VALUE;
+
+ while (low <= high) {
+
+ int mid = (low + high) / 2;
+
+ if (sortedArray[mid] < key) {
+ low = mid + 1;
+ } else if (sortedArray[mid] > key) {
+ high = mid - 1;
+ } else if (sortedArray[mid] == key) {
+ index = mid;
+ break;
+ }
+ }
+ return index;
+ }
+
+ public int runBinarySearchRecursively(int[] sortedArray, int key, int low, int high) {
+
+ int middle = (low + high) / 2;
+ if (high < low) {
+ return -1;
+ }
+
+ if (key == sortedArray[middle]) {
+ return middle;
+ } else if (key < sortedArray[middle]) {
+ return runBinarySearchRecursively(sortedArray, key, low, middle - 1);
+ } else {
+ return runBinarySearchRecursively(sortedArray, key, middle + 1, high);
+ }
+ }
+
+ public int runBinarySearchUsingJavaArrays(int[] sortedArray, Integer key) {
+ int index = Arrays.binarySearch(sortedArray, key);
+ return index;
+ }
+
+ public int runBinarySearchUsingJavaCollections(List sortedList, Integer key) {
+ int index = Collections.binarySearch(sortedList, key);
+ return index;
+ }
+
+}
diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithm.java
diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Node.java
diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/breadthfirstsearch/Tree.java
diff --git a/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java
new file mode 100644
index 0000000000..a6019ea9f9
--- /dev/null
+++ b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/BinaryTree.java
@@ -0,0 +1,227 @@
+package com.baeldung.algorithms.dfs;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.Stack;
+
+public class BinaryTree {
+
+ Node root;
+
+ public void add(int value) {
+ root = addRecursive(root, value);
+ }
+
+ private Node addRecursive(Node current, int value) {
+
+ if (current == null) {
+ return new Node(value);
+ }
+
+ if (value < current.value) {
+ current.left = addRecursive(current.left, value);
+ } else if (value > current.value) {
+ current.right = addRecursive(current.right, value);
+ }
+
+ return current;
+ }
+
+ public boolean isEmpty() {
+ return root == null;
+ }
+
+ public int getSize() {
+ return getSizeRecursive(root);
+ }
+
+ private int getSizeRecursive(Node current) {
+ return current == null ? 0 : getSizeRecursive(current.left) + 1 + getSizeRecursive(current.right);
+ }
+
+ public boolean containsNode(int value) {
+ return containsNodeRecursive(root, value);
+ }
+
+ private boolean containsNodeRecursive(Node current, int value) {
+ if (current == null) {
+ return false;
+ }
+
+ if (value == current.value) {
+ return true;
+ }
+
+ return value < current.value
+ ? containsNodeRecursive(current.left, value)
+ : containsNodeRecursive(current.right, value);
+ }
+
+ public void delete(int value) {
+ root = deleteRecursive(root, value);
+ }
+
+ private Node deleteRecursive(Node current, int value) {
+ if (current == null) {
+ return null;
+ }
+
+ if (value == current.value) {
+ // Case 1: no children
+ if (current.left == null && current.right == null) {
+ return null;
+ }
+
+ // Case 2: only 1 child
+ if (current.right == null) {
+ return current.left;
+ }
+
+ if (current.left == null) {
+ return current.right;
+ }
+
+ // Case 3: 2 children
+ int smallestValue = findSmallestValue(current.right);
+ current.value = smallestValue;
+ current.right = deleteRecursive(current.right, smallestValue);
+ return current;
+ }
+ if (value < current.value) {
+ current.left = deleteRecursive(current.left, value);
+ return current;
+ }
+
+ current.right = deleteRecursive(current.right, value);
+ return current;
+ }
+
+ private int findSmallestValue(Node root) {
+ return root.left == null ? root.value : findSmallestValue(root.left);
+ }
+
+ public void traverseInOrder(Node node) {
+ if (node != null) {
+ traverseInOrder(node.left);
+ visit(node.value);
+ traverseInOrder(node.right);
+ }
+ }
+
+ public void traversePreOrder(Node node) {
+ if (node != null) {
+ visit(node.value);
+ traversePreOrder(node.left);
+ traversePreOrder(node.right);
+ }
+ }
+
+ public void traversePostOrder(Node node) {
+ if (node != null) {
+ traversePostOrder(node.left);
+ traversePostOrder(node.right);
+ visit(node.value);
+ }
+ }
+
+ public void traverseLevelOrder() {
+ if (root == null) {
+ return;
+ }
+
+ Queue nodes = new LinkedList<>();
+ nodes.add(root);
+
+ while (!nodes.isEmpty()) {
+
+ Node node = nodes.remove();
+
+ System.out.print(" " + node.value);
+
+ if (node.left != null) {
+ nodes.add(node.left);
+ }
+
+ if (node.left != null) {
+ nodes.add(node.right);
+ }
+ }
+ }
+
+
+ public void traverseInOrderWithoutRecursion() {
+ Stack stack = new Stack();
+ Node current = root;
+ stack.push(root);
+ while(! stack.isEmpty()) {
+ while(current.left != null) {
+ current = current.left;
+ stack.push(current);
+ }
+ current = stack.pop();
+ visit(current.value);
+ if(current.right != null) {
+ current = current.right;
+ stack.push(current);
+ }
+ }
+ }
+
+ public void traversePreOrderWithoutRecursion() {
+ Stack stack = new Stack();
+ Node current = root;
+ stack.push(root);
+ while(! stack.isEmpty()) {
+ current = stack.pop();
+ visit(current.value);
+
+ if(current.right != null)
+ stack.push(current.right);
+
+ if(current.left != null)
+ stack.push(current.left);
+ }
+ }
+
+ public void traversePostOrderWithoutRecursion() {
+ Stack stack = new Stack();
+ Node prev = root;
+ Node current = root;
+ stack.push(root);
+
+ while (!stack.isEmpty()) {
+ current = stack.peek();
+ boolean hasChild = (current.left != null || current.right != null);
+ boolean isPrevLastChild = (prev == current.right || (prev == current.left && current.right == null));
+
+ if (!hasChild || isPrevLastChild) {
+ current = stack.pop();
+ visit(current.value);
+ prev = current;
+ } else {
+ if (current.right != null) {
+ stack.push(current.right);
+ }
+ if (current.left != null) {
+ stack.push(current.left);
+ }
+ }
+ }
+ }
+
+ private void visit(int value) {
+ System.out.print(" " + value);
+ }
+
+ class Node {
+ int value;
+ Node left;
+ Node right;
+
+ Node(int value) {
+ this.value = value;
+ right = null;
+ left = null;
+ }
+ }
+}
diff --git a/data-structures/src/main/java/com/baeldung/graph/Graph.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java
similarity index 98%
rename from data-structures/src/main/java/com/baeldung/graph/Graph.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java
index 40df2c713a..d2cc723cf9 100644
--- a/data-structures/src/main/java/com/baeldung/graph/Graph.java
+++ b/algorithms-searching/src/main/java/com/baeldung/algorithms/dfs/Graph.java
@@ -1,4 +1,4 @@
-package com.baeldung.graph;
+package com.baeldung.algorithms.dfs;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearch.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/MonteCarloTreeSearch.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/State.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/montecarlo/UCT.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Board.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tictactoe/Position.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Node.java
diff --git a/algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/mcts/tree/Tree.java
diff --git a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/search/StringSearchAlgorithms.java b/algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java
old mode 100755
new mode 100644
similarity index 94%
rename from algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/search/StringSearchAlgorithms.java
rename to algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java
index 45ac53e039..16b45ed886
--- a/algorithms-miscellaneous-4/src/main/java/com/baeldung/algorithms/string/search/StringSearchAlgorithms.java
+++ b/algorithms-searching/src/main/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithms.java
@@ -1,194 +1,194 @@
-package com.baeldung.algorithms.string.search;
-
-import java.math.BigInteger;
-import java.util.Random;
-
-public class StringSearchAlgorithms {
- public static long getBiggerPrime(int m) {
- BigInteger prime = BigInteger.probablePrime(getNumberOfBits(m) + 1, new Random());
- return prime.longValue();
- }
-
- public static long getLowerPrime(long number) {
- BigInteger prime = BigInteger.probablePrime(getNumberOfBits(number) - 1, new Random());
- return prime.longValue();
- }
-
- private static int getNumberOfBits(final int number) {
- return Integer.SIZE - Integer.numberOfLeadingZeros(number);
- }
-
- private static int getNumberOfBits(final long number) {
- return Long.SIZE - Long.numberOfLeadingZeros(number);
- }
-
- public static int simpleTextSearch(char[] pattern, char[] text) {
- int patternSize = pattern.length;
- int textSize = text.length;
-
- int i = 0;
-
- while ((i + patternSize) <= textSize) {
- int j = 0;
- while (text[i + j] == pattern[j]) {
- j += 1;
- if (j >= patternSize)
- return i;
- }
- i += 1;
- }
-
- return -1;
- }
-
- public static int RabinKarpMethod(char[] pattern, char[] text) {
- int patternSize = pattern.length; // m
- int textSize = text.length; // n
-
- long prime = getBiggerPrime(patternSize);
-
- long r = 1;
- for (int i = 0; i < patternSize - 1; i++) {
- r *= 2;
- r = r % prime;
- }
-
- long[] t = new long[textSize];
- t[0] = 0;
-
- long pfinger = 0;
-
- for (int j = 0; j < patternSize; j++) {
- t[0] = (2 * t[0] + text[j]) % prime;
- pfinger = (2 * pfinger + pattern[j]) % prime;
- }
-
- int i = 0;
- boolean passed = false;
-
- int diff = textSize - patternSize;
- for (i = 0; i <= diff; i++) {
- if (t[i] == pfinger) {
- passed = true;
- for (int k = 0; k < patternSize; k++) {
- if (text[i + k] != pattern[k]) {
- passed = false;
- break;
- }
- }
-
- if (passed) {
- return i;
- }
- }
-
- if (i < diff) {
- long value = 2 * (t[i] - r * text[i]) + text[i + patternSize];
- t[i + 1] = ((value % prime) + prime) % prime;
- }
- }
- return -1;
-
- }
-
- public static int KnuthMorrisPrattSearch(char[] pattern, char[] text) {
- int patternSize = pattern.length; // m
- int textSize = text.length; // n
-
- int i = 0, j = 0;
-
- int[] shift = KnuthMorrisPrattShift(pattern);
-
- while ((i + patternSize) <= textSize) {
- while (text[i + j] == pattern[j]) {
- j += 1;
- if (j >= patternSize)
- return i;
- }
-
- if (j > 0) {
- i += shift[j - 1];
- j = Math.max(j - shift[j - 1], 0);
- } else {
- i++;
- j = 0;
- }
- }
- return -1;
- }
-
- public static int[] KnuthMorrisPrattShift(char[] pattern) {
- int patternSize = pattern.length;
-
- int[] shift = new int[patternSize];
- shift[0] = 1;
-
- int i = 1, j = 0;
-
- while ((i + j) < patternSize) {
- if (pattern[i + j] == pattern[j]) {
- shift[i + j] = i;
- j++;
- } else {
- if (j == 0)
- shift[i] = i + 1;
-
- if (j > 0) {
- i = i + shift[j - 1];
- j = Math.max(j - shift[j - 1], 0);
- } else {
- i = i + 1;
- j = 0;
- }
- }
- }
- return shift;
- }
-
- public static int BoyerMooreHorspoolSimpleSearch(char[] pattern, char[] text) {
- int patternSize = pattern.length;
- int textSize = text.length;
-
- int i = 0, j = 0;
-
- while ((i + patternSize) <= textSize) {
- j = patternSize - 1;
- while (text[i + j] == pattern[j]) {
- j--;
- if (j < 0)
- return i;
- }
- i++;
- }
- return -1;
- }
-
- public static int BoyerMooreHorspoolSearch(char[] pattern, char[] text) {
-
- int shift[] = new int[256];
-
- for (int k = 0; k < 256; k++) {
- shift[k] = pattern.length;
- }
-
- for (int k = 0; k < pattern.length - 1; k++) {
- shift[pattern[k]] = pattern.length - 1 - k;
- }
-
- int i = 0, j = 0;
-
- while ((i + pattern.length) <= text.length) {
- j = pattern.length - 1;
-
- while (text[i + j] == pattern[j]) {
- j -= 1;
- if (j < 0)
- return i;
- }
-
- i = i + shift[text[i + pattern.length - 1]];
-
- }
- return -1;
- }
-}
+package com.baeldung.algorithms.textsearch;
+
+import java.math.BigInteger;
+import java.util.Random;
+
+public class TextSearchAlgorithms {
+ public static long getBiggerPrime(int m) {
+ BigInteger prime = BigInteger.probablePrime(getNumberOfBits(m) + 1, new Random());
+ return prime.longValue();
+ }
+
+ public static long getLowerPrime(long number) {
+ BigInteger prime = BigInteger.probablePrime(getNumberOfBits(number) - 1, new Random());
+ return prime.longValue();
+ }
+
+ private static int getNumberOfBits(final int number) {
+ return Integer.SIZE - Integer.numberOfLeadingZeros(number);
+ }
+
+ private static int getNumberOfBits(final long number) {
+ return Long.SIZE - Long.numberOfLeadingZeros(number);
+ }
+
+ public static int simpleTextSearch(char[] pattern, char[] text) {
+ int patternSize = pattern.length;
+ int textSize = text.length;
+
+ int i = 0;
+
+ while ((i + patternSize) <= textSize) {
+ int j = 0;
+ while (text[i + j] == pattern[j]) {
+ j += 1;
+ if (j >= patternSize)
+ return i;
+ }
+ i += 1;
+ }
+
+ return -1;
+ }
+
+ public static int RabinKarpMethod(char[] pattern, char[] text) {
+ int patternSize = pattern.length; // m
+ int textSize = text.length; // n
+
+ long prime = getBiggerPrime(patternSize);
+
+ long r = 1;
+ for (int i = 0; i < patternSize - 1; i++) {
+ r *= 2;
+ r = r % prime;
+ }
+
+ long[] t = new long[textSize];
+ t[0] = 0;
+
+ long pfinger = 0;
+
+ for (int j = 0; j < patternSize; j++) {
+ t[0] = (2 * t[0] + text[j]) % prime;
+ pfinger = (2 * pfinger + pattern[j]) % prime;
+ }
+
+ int i = 0;
+ boolean passed = false;
+
+ int diff = textSize - patternSize;
+ for (i = 0; i <= diff; i++) {
+ if (t[i] == pfinger) {
+ passed = true;
+ for (int k = 0; k < patternSize; k++) {
+ if (text[i + k] != pattern[k]) {
+ passed = false;
+ break;
+ }
+ }
+
+ if (passed) {
+ return i;
+ }
+ }
+
+ if (i < diff) {
+ long value = 2 * (t[i] - r * text[i]) + text[i + patternSize];
+ t[i + 1] = ((value % prime) + prime) % prime;
+ }
+ }
+ return -1;
+
+ }
+
+ public static int KnuthMorrisPrattSearch(char[] pattern, char[] text) {
+ int patternSize = pattern.length; // m
+ int textSize = text.length; // n
+
+ int i = 0, j = 0;
+
+ int[] shift = KnuthMorrisPrattShift(pattern);
+
+ while ((i + patternSize) <= textSize) {
+ while (text[i + j] == pattern[j]) {
+ j += 1;
+ if (j >= patternSize)
+ return i;
+ }
+
+ if (j > 0) {
+ i += shift[j - 1];
+ j = Math.max(j - shift[j - 1], 0);
+ } else {
+ i++;
+ j = 0;
+ }
+ }
+ return -1;
+ }
+
+ public static int[] KnuthMorrisPrattShift(char[] pattern) {
+ int patternSize = pattern.length;
+
+ int[] shift = new int[patternSize];
+ shift[0] = 1;
+
+ int i = 1, j = 0;
+
+ while ((i + j) < patternSize) {
+ if (pattern[i + j] == pattern[j]) {
+ shift[i + j] = i;
+ j++;
+ } else {
+ if (j == 0)
+ shift[i] = i + 1;
+
+ if (j > 0) {
+ i = i + shift[j - 1];
+ j = Math.max(j - shift[j - 1], 0);
+ } else {
+ i = i + 1;
+ j = 0;
+ }
+ }
+ }
+ return shift;
+ }
+
+ public static int BoyerMooreHorspoolSimpleSearch(char[] pattern, char[] text) {
+ int patternSize = pattern.length;
+ int textSize = text.length;
+
+ int i = 0, j = 0;
+
+ while ((i + patternSize) <= textSize) {
+ j = patternSize - 1;
+ while (text[i + j] == pattern[j]) {
+ j--;
+ if (j < 0)
+ return i;
+ }
+ i++;
+ }
+ return -1;
+ }
+
+ public static int BoyerMooreHorspoolSearch(char[] pattern, char[] text) {
+
+ int shift[] = new int[256];
+
+ for (int k = 0; k < 256; k++) {
+ shift[k] = pattern.length;
+ }
+
+ for (int k = 0; k < pattern.length - 1; k++) {
+ shift[pattern[k]] = pattern.length - 1 - k;
+ }
+
+ int i = 0, j = 0;
+
+ while ((i + pattern.length) <= text.length) {
+ j = pattern.length - 1;
+
+ while (text[i + j] == pattern[j]) {
+ j -= 1;
+ if (j < 0)
+ return i;
+ }
+
+ i = i + shift[text[i + pattern.length - 1]];
+
+ }
+ return -1;
+ }
+}
diff --git a/algorithms-searching/src/main/resources/logback.xml b/algorithms-searching/src/main/resources/logback.xml
new file mode 100644
index 0000000000..7d900d8ea8
--- /dev/null
+++ b/algorithms-searching/src/main/resources/logback.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
similarity index 94%
rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
rename to algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
index 826682d373..eb3fb4f718 100644
--- a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
+++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/binarysearch/BinarySearchUnitTest.java
@@ -1,43 +1,41 @@
-package com.baeldung.algorithms.binarysearch;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.junit.Assert;
-import org.junit.Test;
-import com.baeldung.algorithms.binarysearch.BinarySearch;
-
-public class BinarySearchUnitTest {
-
- int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
- int key = 6;
- int expectedIndexForSearchKey = 7;
- int low = 0;
- int high = sortedArray.length - 1;
- List sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
- }
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
- }
-
- @Test
- public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
- }
-
- @Test
- public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
- BinarySearch binSearch = new BinarySearch();
- Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
- }
-
-}
+package com.baeldung.algorithms.binarysearch;
+
+import java.util.Arrays;
+import java.util.List;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class BinarySearchUnitTest {
+
+ int[] sortedArray = { 0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9 };
+ int key = 6;
+ int expectedIndexForSearchKey = 7;
+ int low = 0;
+ int high = sortedArray.length - 1;
+ List sortedList = Arrays.asList(0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9);
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunIterativelyForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchIteratively(sortedArray, key, low, high));
+ }
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunRecursivelyForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchRecursively(sortedArray, key, low, high));
+ }
+
+ @Test
+ public void givenASortedArrayOfIntegers_whenBinarySearchRunUsingArraysClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaArrays(sortedArray, key));
+ }
+
+ @Test
+ public void givenASortedListOfIntegers_whenBinarySearchRunUsingCollectionsClassStaticMethodForANumber_thenGetIndexOfTheNumber() {
+ BinarySearch binSearch = new BinarySearch();
+ Assert.assertEquals(expectedIndexForSearchKey, binSearch.runBinarySearchUsingJavaCollections(sortedList, key));
+ }
+
+}
diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java
rename to algorithms-searching/src/test/java/com/baeldung/algorithms/breadthfirstsearch/BreadthFirstSearchAlgorithmUnitTest.java
diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java
new file mode 100644
index 0000000000..076da14f81
--- /dev/null
+++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/BinaryTreeUnitTest.java
@@ -0,0 +1,136 @@
+package com.baeldung.algorithms.dfs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class BinaryTreeUnitTest {
+
+ @Test
+ public void givenABinaryTree_WhenAddingElements_ThenTreeNotEmpty() {
+
+ BinaryTree bt = createBinaryTree();
+
+ assertTrue(!bt.isEmpty());
+ }
+
+ @Test
+ public void givenABinaryTree_WhenAddingElements_ThenTreeContainsThoseElements() {
+
+ BinaryTree bt = createBinaryTree();
+
+ assertTrue(bt.containsNode(6));
+ assertTrue(bt.containsNode(4));
+
+ assertFalse(bt.containsNode(1));
+ }
+
+ @Test
+ public void givenABinaryTree_WhenAddingExistingElement_ThenElementIsNotAdded() {
+
+ BinaryTree bt = createBinaryTree();
+
+ int initialSize = bt.getSize();
+
+ assertTrue(bt.containsNode(3));
+ bt.add(3);
+ assertEquals(initialSize, bt.getSize());
+ }
+
+ @Test
+ public void givenABinaryTree_WhenLookingForNonExistingElement_ThenReturnsFalse() {
+
+ BinaryTree bt = createBinaryTree();
+
+ assertFalse(bt.containsNode(99));
+ }
+
+ @Test
+ public void givenABinaryTree_WhenDeletingElements_ThenTreeDoesNotContainThoseElements() {
+
+ BinaryTree bt = createBinaryTree();
+
+ assertTrue(bt.containsNode(9));
+ bt.delete(9);
+ assertFalse(bt.containsNode(9));
+ }
+
+ @Test
+ public void givenABinaryTree_WhenDeletingNonExistingElement_ThenTreeDoesNotDelete() {
+
+ BinaryTree bt = createBinaryTree();
+
+ int initialSize = bt.getSize();
+
+ assertFalse(bt.containsNode(99));
+ bt.delete(99);
+ assertFalse(bt.containsNode(99));
+ assertEquals(initialSize, bt.getSize());
+ }
+
+ @Test
+ public void it_deletes_the_root() {
+ int value = 12;
+ BinaryTree bt = new BinaryTree();
+ bt.add(value);
+
+ assertTrue(bt.containsNode(value));
+ bt.delete(value);
+ assertFalse(bt.containsNode(value));
+ }
+
+ @Test
+ public void givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
+
+ BinaryTree bt = createBinaryTree();
+
+ bt.traverseInOrder(bt.root);
+ System.out.println();
+ bt.traverseInOrderWithoutRecursion();
+ }
+
+ @Test
+ public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() {
+
+ BinaryTree bt = createBinaryTree();
+
+ bt.traversePreOrder(bt.root);
+ System.out.println();
+ bt.traversePreOrderWithoutRecursion();
+ }
+
+ @Test
+ public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() {
+
+ BinaryTree bt = createBinaryTree();
+
+ bt.traversePostOrder(bt.root);
+ System.out.println();
+ bt.traversePostOrderWithoutRecursion();
+ }
+
+ @Test
+ public void givenABinaryTree_WhenTraversingLevelOrder_ThenPrintValues() {
+
+ BinaryTree bt = createBinaryTree();
+
+ bt.traverseLevelOrder();
+ }
+
+ private BinaryTree createBinaryTree() {
+ BinaryTree bt = new BinaryTree();
+
+ bt.add(6);
+ bt.add(4);
+ bt.add(8);
+ bt.add(3);
+ bt.add(5);
+ bt.add(7);
+ bt.add(9);
+
+ return bt;
+ }
+
+}
diff --git a/data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java
similarity index 92%
rename from data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java
rename to algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java
index 09b92115d2..715bb55fcb 100644
--- a/data-structures/src/test/java/com/baeldung/graph/GraphUnitTest.java
+++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/dfs/GraphUnitTest.java
@@ -1,7 +1,8 @@
-package com.baeldung.graph;
+package com.baeldung.algorithms.dfs;
import java.util.List;
+import com.baeldung.algorithms.dfs.Graph;
import org.junit.Test;
public class GraphUnitTest {
diff --git a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java
similarity index 100%
rename from algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java
rename to algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java
index 8ad962055e..cabedcefad 100644
--- a/algorithms-miscellaneous-3/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java
+++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/interpolationsearch/InterpolationSearchUnitTest.java
@@ -1,10 +1,10 @@
package com.baeldung.algorithms.interpolationsearch;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
import org.junit.Before;
import org.junit.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
public class InterpolationSearchUnitTest {
private int[] myData;
diff --git a/algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java
similarity index 100%
rename from algorithms-miscellaneous-1/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java
rename to algorithms-searching/src/test/java/com/baeldung/algorithms/mcts/MCTSUnitTest.java
diff --git a/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java b/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java
new file mode 100644
index 0000000000..543ccb912f
--- /dev/null
+++ b/algorithms-searching/src/test/java/com/baeldung/algorithms/textsearch/TextSearchAlgorithmsUnitTest.java
@@ -0,0 +1,23 @@
+package com.baeldung.algorithms.textsearch;
+
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TextSearchAlgorithmsUnitTest {
+
+
+ @Test
+ public void testStringSearchAlgorithms() {
+ String text = "This is some nice text.";
+ String pattern = "some";
+
+ int realPosition = text.indexOf(pattern);
+ Assert.assertTrue(realPosition == TextSearchAlgorithms.simpleTextSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == TextSearchAlgorithms.RabinKarpMethod(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == TextSearchAlgorithms.KnuthMorrisPrattSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == TextSearchAlgorithms.BoyerMooreHorspoolSimpleSearch(pattern.toCharArray(), text.toCharArray()));
+ Assert.assertTrue(realPosition == TextSearchAlgorithms.BoyerMooreHorspoolSearch(pattern.toCharArray(), text.toCharArray()));
+ }
+
+}
diff --git a/data-structures/README.md b/data-structures/README.md
index b7f15c2eb8..7eeda7c64f 100644
--- a/data-structures/README.md
+++ b/data-structures/README.md
@@ -6,4 +6,3 @@ This module contains articles about data structures in Java
- [The Trie Data Structure in Java](https://www.baeldung.com/trie-java)
- [Implementing a Binary Tree in Java](https://www.baeldung.com/java-binary-tree)
-- [Depth First Search in Java](https://www.baeldung.com/java-depth-first-search)
diff --git a/pom.xml b/pom.xml
index be440ad033..9ab3e33439 100644
--- a/pom.xml
+++ b/pom.xml
@@ -341,6 +341,7 @@
algorithms-miscellaneous-4
algorithms-miscellaneous-5
algorithms-sorting
+ algorithms-searching
animal-sniffer-mvn-plugin
annotations
antlr
@@ -1117,6 +1118,7 @@
algorithms-miscellaneous-4
algorithms-miscellaneous-5
algorithms-sorting
+ algorithms-searching
animal-sniffer-mvn-plugin
annotations
antlr