Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 184 additions & 0 deletions src/main/java/BinaryTree.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import java.util.Objects;

/**Вариант 12 -- бинарное дерево поиска [Java]
Хранит целые числа в виде бинарного дерева поиска. Дерево не может содержать
одно и то же число более одного раза.
Методы: добавление числа, удаление числа, поиск числа в дереве, определение
соседей числа в дереве (предок, левый потомок, правый потомок).*/

// BinaryTree.add(5) - добавить в дерево узел со значением 5
// BinaryTree.remove(5) - удалить из дерева узел со значением 5
// BinaryTree.search(5) - узнать, есть ли в дереве узел со значением 5 (boolean)
// BinaryTree.parent(5) - определить предка узла со значением 5
// BinaryTree.leftChild(5) - определить левого потомка узла со значением 5
// BinaryTree.rightChild(5) - определить правого потомка узла со значением 5

public class BinaryTree {


Node root;

private Node addNode(Node current, int value) {
if (current == null || current.value == -1) return new Node(value);
if (value < current.value) current.left = addNode(current.left, value);
else if (value > current.value) current.right = addNode(current.right, value);
else return current;
return current;
}

public void add(int value) {
root = addNode(root, value);
}

private boolean searchNode(Node current, int value) {
if (current == null) return false;
if (value == current.value) return true;
if (value < current.value) return searchNode(current.left, value);
else return searchNode(current.right, value);
}

public boolean search(int value) {
return searchNode(root, value);
}

private int findMaxOfLeft(Node start) {
if (start.right == null) return start.value;
else return findMaxOfLeft(start.right);
}

Node potentialParent = null;
int leftOrRight = -1; //0 - пошли к левому ребенку, 1 - пошли к правому

private Node removeNode(Node current, int value) {
if (current == null) return null;
if (value == current.value) {
if (current.left == null && current.right == null) {
if (potentialParent != null) {
if (leftOrRight == 1) potentialParent.right = null;
else potentialParent.left = null;
}
return null;
}
if (current.left == null) {
if (potentialParent != null) {
if (leftOrRight == 1) potentialParent.right = current;
else potentialParent.left = current;
}
return current.right;
}
if (current.right == null) {
if (potentialParent != null) {
if (leftOrRight == 1) potentialParent.right = current;
else potentialParent.left = current;
}
return current.left;
}
else {
if (potentialParent != null) {
if (leftOrRight == 1) potentialParent.right = current;
else potentialParent.left = current;
}
current.value = findMaxOfLeft(current.left);
current.left = removeNode(current.left, findMaxOfLeft(current.left));
return current;
}
}
if (value < current.value) {
potentialParent = current;
leftOrRight = 0;
current.left = removeNode(current.left, value);
}
else {
potentialParent = current;
leftOrRight = 1;
current.right = removeNode(current.right, value);
}
return current;
}

public void remove(int value) {
root = removeNode(root, value);
}

private int parentNode(Node current, int value) {
if (!search(value) || current.value == value) return -1;
if ((current.left != null && current.left.value == value)
|| (current.right != null && current.right.value == value)) return current.value;
if (value < current.value) return parentNode(current.left, value);
else return parentNode(current.right, value);
}

public int parent(int value) {
return parentNode(root, value);
}

private int leftChildNode(Node current, int value) {
if (!search(value)) return -1;
if (current.value == value && current.left != null) return current.left.value;
if (current.value > value && current.left != null) return leftChildNode(current.left, value);
if (current.value < value && current.right != null) return leftChildNode(current.right, value);
else return -1;
}

public int leftChild(int value) {
return leftChildNode(root, value);
}

private int rightChildNode(Node current, int value) {
if (!search(value)) return -1;
if (current.value == value && current.right != null) return current.right.value;
if (current.value > value && current.left != null) return rightChildNode(current.left, value);
if (current.value < value && current.right != null) return rightChildNode(current.right, value);
else return -1;
}

public int rightChild(int value) {
return rightChildNode(root, value);
}

public static void main(String[] args) {
BinaryTree a = new BinaryTree();
a.add(10);
a.add(300);
a.add(150);
a.add(75);
a.add(225);
a.add(50);
a.add(100);
a.add(200);
a.add(250);
System.out.println(a.leftChild(300));
System.out.println(a.leftChild(150));
System.out.println(a.rightChild(75));
a.remove(150);
System.out.println(a.leftChild(300));
System.out.println(a.rightChild(75));
}

class Node {
int value;
Node left;
Node right;

Node(int value) {
this.value = value;
right = null;
left = null;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return value == node.value && Objects.equals(left, node.left) && Objects.equals(right, node.right);
}

@Override
public int hashCode() {
return Objects.hash(value, left, right);
}
}
}


76 changes: 76 additions & 0 deletions src/test/java/BinaryTreeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class BinaryTreeTest {

BinaryTree tree1 = new BinaryTree();
BinaryTree tree2 = new BinaryTree();

@Test
public void testAdd() {
tree1.add(2);
tree2.add(2);
tree1.add(3);
tree2.add(3);
assertEquals(tree1.root, tree2.root);
assertTrue(tree1.search(2));
tree1.remove(2);
assertNotEquals(tree1.root, tree2.root);
}

@Test
public void testRemove() {
tree1.add(2);
tree2.add(2);
tree1.add(3);
tree2.add(3);
tree2.add(1);
tree2.remove(1);
assertEquals(tree1.root, tree2.root);
assertFalse(tree2.search(1));
tree1.remove(2);
assertNotEquals(tree1.root, tree2.root);
}

@Test
public void testSearch() {
assertFalse(tree1.search(5));
tree1.add(5);
assertTrue(tree1.search(5));
tree1.add(1);
assertTrue(tree1.search(1));
}

@Test
public void testParent() {
tree1.add(3);
tree1.add(1);
tree1.add(4);
tree1.add(5);
assertEquals(-1, tree1.parent(3));
assertEquals(3, tree1.parent(1));
assertEquals(3, tree1.parent(4));
assertEquals(4, tree1.parent(5));
}

@Test
public void testLeftChild() {
tree1.add(3);
tree1.add(2);
tree1.add(1);
assertEquals(-1, tree1.leftChild(1));
assertEquals(1, tree1.leftChild(2));
assertEquals(2, tree1.leftChild(3));
}

@Test
public void testRightChild() {
tree1.add(3);
tree1.add(4);
tree1.add(5);
assertEquals(-1, tree1.rightChild(5));
assertEquals(5, tree1.rightChild(4));
assertEquals(4, tree1.rightChild(3));
}
}