Add data structures as a separate module (#3518)
* Remove data structures from core-java * Add data-structures * Update README with links to articles * Add parent module reference
This commit is contained in:
committed by
Grzegorz Piwowarek
parent
2b50c4c341
commit
4c0a39a342
@@ -1,161 +0,0 @@
|
||||
package com.baeldung.tree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
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) {
|
||||
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);
|
||||
System.out.print(" " + node.value);
|
||||
traverseInOrder(node.right);
|
||||
}
|
||||
}
|
||||
|
||||
public void traversePreOrder(Node node) {
|
||||
if (node != null) {
|
||||
System.out.print(" " + node.value);
|
||||
traversePreOrder(node.left);
|
||||
traversePreOrder(node.right);
|
||||
}
|
||||
}
|
||||
|
||||
public void traversePostOrder(Node node) {
|
||||
if (node != null) {
|
||||
traversePostOrder(node.left);
|
||||
traversePostOrder(node.right);
|
||||
System.out.print(" " + node.value);
|
||||
}
|
||||
}
|
||||
|
||||
public void traverseLevelOrder() {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Queue<Node> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Node {
|
||||
int value;
|
||||
Node left;
|
||||
Node right;
|
||||
|
||||
Node(int value) {
|
||||
this.value = value;
|
||||
right = null;
|
||||
left = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
package com.baeldung.trie;
|
||||
|
||||
public class Trie {
|
||||
private TrieNode root;
|
||||
|
||||
Trie() {
|
||||
root = new TrieNode();
|
||||
}
|
||||
|
||||
public void insert(String word) {
|
||||
TrieNode current = root;
|
||||
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
current = current.getChildren().computeIfAbsent(word.charAt(i), c -> new TrieNode());
|
||||
}
|
||||
current.setEndOfWord(true);
|
||||
}
|
||||
|
||||
public boolean delete(String word) {
|
||||
return delete(root, word, 0);
|
||||
}
|
||||
|
||||
public boolean containsNode(String word) {
|
||||
TrieNode current = root;
|
||||
|
||||
for (int i = 0; i < word.length(); i++) {
|
||||
char ch = word.charAt(i);
|
||||
TrieNode node = current.getChildren().get(ch);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
current = node;
|
||||
}
|
||||
return current.isEndOfWord();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
|
||||
private boolean delete(TrieNode current, String word, int index) {
|
||||
if (index == word.length()) {
|
||||
if (!current.isEndOfWord()) {
|
||||
return false;
|
||||
}
|
||||
current.setEndOfWord(false);
|
||||
return current.getChildren().isEmpty();
|
||||
}
|
||||
char ch = word.charAt(index);
|
||||
TrieNode node = current.getChildren().get(ch);
|
||||
if (node == null) {
|
||||
return false;
|
||||
}
|
||||
boolean shouldDeleteCurrentNode = delete(node, word, index + 1);
|
||||
|
||||
if (shouldDeleteCurrentNode) {
|
||||
current.getChildren().remove(ch);
|
||||
return current.getChildren().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.baeldung.trie;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class TrieNode {
|
||||
private Map<Character, TrieNode> children;
|
||||
private boolean endOfWord;
|
||||
|
||||
public TrieNode() {
|
||||
children = new HashMap<>();
|
||||
endOfWord = false;
|
||||
}
|
||||
|
||||
public Map<Character, TrieNode> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(Map<Character, TrieNode> children) {
|
||||
this.children = children;
|
||||
}
|
||||
|
||||
public boolean isEndOfWord() {
|
||||
return endOfWord;
|
||||
}
|
||||
|
||||
public void setEndOfWord(boolean endOfWord) {
|
||||
this.endOfWord = endOfWord;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
package com.baeldung.tree;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class BinaryTreeTest {
|
||||
|
||||
@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 givenABinaryTree_WhenTraversingInOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = createBinaryTree();
|
||||
|
||||
bt.traverseInOrder(bt.root);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingPreOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = createBinaryTree();
|
||||
|
||||
bt.traversePreOrder(bt.root);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenABinaryTree_WhenTraversingPostOrder_ThenPrintValues() {
|
||||
|
||||
BinaryTree bt = createBinaryTree();
|
||||
|
||||
bt.traversePostOrder(bt.root);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.baeldung.trie;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TrieTest {
|
||||
|
||||
@Test
|
||||
public void whenEmptyTrie_thenNoElements() {
|
||||
Trie trie = new Trie();
|
||||
|
||||
assertFalse(trie.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenATrie_whenAddingElements_thenTrieNotEmpty() {
|
||||
Trie trie = createExampleTrie();
|
||||
|
||||
assertFalse(trie.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenATrie_whenAddingElements_thenTrieHasThoseElements() {
|
||||
Trie trie = createExampleTrie();
|
||||
|
||||
assertFalse(trie.containsNode("3"));
|
||||
assertFalse(trie.containsNode("vida"));
|
||||
|
||||
assertTrue(trie.containsNode("Programming"));
|
||||
assertTrue(trie.containsNode("is"));
|
||||
assertTrue(trie.containsNode("a"));
|
||||
assertTrue(trie.containsNode("way"));
|
||||
assertTrue(trie.containsNode("of"));
|
||||
assertTrue(trie.containsNode("life"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenATrie_whenLookingForNonExistingElement_thenReturnsFalse() {
|
||||
Trie trie = createExampleTrie();
|
||||
|
||||
assertFalse(trie.containsNode("99"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenATrie_whenDeletingElements_thenTreeDoesNotContainThoseElements() {
|
||||
|
||||
Trie trie = createExampleTrie();
|
||||
|
||||
assertTrue(trie.containsNode("Programming"));
|
||||
trie.delete("Programming");
|
||||
assertFalse(trie.containsNode("Programming"));
|
||||
}
|
||||
|
||||
private Trie createExampleTrie() {
|
||||
Trie trie = new Trie();
|
||||
|
||||
trie.insert("Programming");
|
||||
trie.insert("is");
|
||||
trie.insert("a");
|
||||
trie.insert("way");
|
||||
trie.insert("of");
|
||||
trie.insert("life");
|
||||
|
||||
return trie;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user