Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVL 트리 구현... (미완성) #41

Merged
merged 7 commits into from
Aug 23, 2020
106 changes: 106 additions & 0 deletions yoonexample/src/main/java/search/binarysearchtree/AVLTreeNode.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package search.binarysearchtree;

import java.util.Comparator;
import tree.binarytree.BinaryTreeNode;

public class AVLTreeNode<E> extends LinkedBinarySearchTreeNode<E> {

public AVLTreeNode(E data, Comparator<E> comparator) {
super(data, comparator);
}

@Override
public void insert(E data) {
super.insert(data);
rebalance();
}

@Override
public BinaryTreeNode<E> remove(E target) {
BinaryTreeNode<E> removeNode = super.remove(target);
rebalance();
return removeNode;
}

private int getHeight(BinaryTreeNode<E> binaryTreeNode) {
if (binaryTreeNode == null) {
return 0;
}
int leftHeight = getHeight(binaryTreeNode.getLeftSubTree());
int rightHeight = getHeight(binaryTreeNode.getRightSubTree());

return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1; // 큰 쪽의 높이 반환
}

private int getEquilibriumFactor(BinaryTreeNode<E> binaryTreeNode) {
if (binaryTreeNode == null) {
return 0;
}

int leftHeight = getHeight(binaryTreeNode.getLeftSubTree());
int rightHeight = getHeight(binaryTreeNode.getRightSubTree());

return leftHeight - rightHeight;
}

private BinaryTreeNode<E> rotateLL(BinaryTreeNode<E> binaryTreeNode) {
// LL 회전을 위한 준비
BinaryTreeNode<E> parentNode = binaryTreeNode;
BinaryTreeNode<E> childNode = parentNode.getLeftSubTree();

// LL 회전
parentNode.changeLeftSubTree(childNode.getRightSubTree());
childNode.changeRightSubTree(parentNode);

return childNode; // 변경된 루트 노드 반환
}

private BinaryTreeNode<E> rotateRR(BinaryTreeNode<E> binaryTreeNode) {
// RR 회전을 위한 준비
BinaryTreeNode<E> parentNode = binaryTreeNode;
BinaryTreeNode<E> childNode = parentNode.getRightSubTree();

// RR 회전
parentNode.changeRightSubTree(childNode.getLeftSubTree());
childNode.changeLeftSubTree(parentNode);

return childNode; // 변경된 루트 노드 반환
}

private BinaryTreeNode<E> rotateLR(BinaryTreeNode<E> binaryTreeNode) {
// LR 회전을 위한 준비
BinaryTreeNode<E> parentNode = binaryTreeNode;
BinaryTreeNode<E> childNode = parentNode.getLeftSubTree();

parentNode.changeLeftSubTree(rotateRR(childNode)); // 부분적 RR회전
return rotateLL(parentNode); // LL회전
}

private BinaryTreeNode<E> rotateRL(BinaryTreeNode<E> binaryTreeNode) {
// RL 회전을 위한 준비
BinaryTreeNode<E> parentNode = binaryTreeNode;
BinaryTreeNode<E> childNode = parentNode.getLeftSubTree();

parentNode.changeRightSubTree(rotateLL(childNode)); // 부분적 LL회전
return rotateRR(parentNode); // RR회전
}

private void rebalance() {
int equilibriumFactor = getEquilibriumFactor(super.node);

if (equilibriumFactor > 1) { // LL OR LR
if (getEquilibriumFactor(super.node.getLeftSubTree()) > 0) {
super.node = rotateLL(super.node);
} else {
super.node = rotateLR(super.node);
}
}
if (equilibriumFactor < -1) { // RR OR RL
if (getEquilibriumFactor(super.node.getRightSubTree()) < 0) {
super.node = rotateRR(super.node);
} else {
super.node = rotateRL(super.node);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
public class LinkedBinarySearchTreeNode<E> implements BinarySearchTreeNode<E> {

private final Comparator<E> comparator;
private BinaryTreeNode<E> node;
protected BinaryTreeNode<E> node;

public LinkedBinarySearchTreeNode(E data, Comparator<E> comparator) {
this.node = new LinkedBinaryTreeNode<>(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,106 @@ class BinarySearchTreeNodeTest {
assertThat(bstRoot.search(8).getData())
.isEqualTo(bstRoot.remove(8).getData());
}

@Test
@DisplayName("AVL_트리_테스트")
void AVL_트리_테스트() {
BinarySearchTreeNode<Integer> bstRoot = new AVLTreeNode<>(1, (Comparator.comparingInt(o -> o)));
BinaryTreeNode<Integer> searchNode;

bstRoot.insert(5);
bstRoot.insert(6);
bstRoot.insert(2);
bstRoot.insert(8);
bstRoot.insert(3);
bstRoot.insert(9);

searchNode = bstRoot.search(1);
assertThat(searchNode).isNotNull();
assertThat(searchNode.getData()).isEqualTo(1);

searchNode = bstRoot.search(4);
assertThat(searchNode).isNull();

searchNode = bstRoot.search(6);
assertThat(searchNode).isNotNull();
assertThat(searchNode.getData()).isEqualTo(6);

searchNode = bstRoot.search(7);
assertThat(searchNode).isNull();

// BinaryTreeNode<Integer> rootNode = bstRoot.search(5);
// BinaryTreeNode<Integer> rootNodeLeftSubTree = rootNode.getLeftSubTree();
// BinaryTreeNode<Integer> rootNodeRightSubTree = rootNode.getRightSubTree();
//
// assertThat(rootNode.getData()).isEqualTo(5);
// assertThat(rootNodeLeftSubTree.getData()).isEqualTo(2);
// assertThat(rootNodeRightSubTree.getData()).isEqualTo(8);
// assertThat(rootNodeLeftSubTree.getLeftSubTree().getData()).isEqualTo(1);
// assertThat(rootNodeLeftSubTree.getRightSubTree().getData()).isEqualTo(3);
// assertThat(rootNodeRightSubTree.getLeftSubTree().getData()).isEqualTo(6);
// assertThat(rootNodeRightSubTree.getRightSubTree().getData()).isEqualTo(9);
}

@Test
@DisplayName("AVL_트리_제거_테스트")
void AVL_트리_제거_테스트() {
BinarySearchTreeNode<Integer> bstRoot = new AVLTreeNode<>(5, (Comparator.comparingInt(o -> o)));

bstRoot.insert(1);
bstRoot.insert(2);
bstRoot.insert(3);
bstRoot.insert(7);
bstRoot.insert(8);
bstRoot.insert(9);

// BinaryTreeNode<Integer> rootNode = bstRoot.search(2);
// BinaryTreeNode<Integer> rootNodeLeftSubTree = rootNode.getLeftSubTree();
// BinaryTreeNode<Integer> rootNodeRightSubTree = rootNode.getRightSubTree();
// BinaryTreeNode<Integer> rootNodeRightSubTreeLeftSubTree = rootNodeRightSubTree.getLeftSubTree();
//
// assertThat(rootNode.getData()).isEqualTo(2);
// assertThat(rootNodeLeftSubTree.getData()).isEqualTo(1);
// assertThat(rootNodeRightSubTree.getData()).isEqualTo(8);
// assertThat(rootNodeRightSubTreeLeftSubTree.getData()).isEqualTo(5);
// assertThat(rootNodeRightSubTree.getRightSubTree().getData()).isEqualTo(9);
// assertThat(rootNodeRightSubTreeLeftSubTree.getLeftSubTree().getData()).isEqualTo(3);
// assertThat(rootNodeRightSubTreeLeftSubTree.getRightSubTree().getData()).isEqualTo(7);

assertThat(bstRoot.search(2).getData()).isEqualTo(bstRoot.remove(2).getData());
assertThat(bstRoot.search(7).getData()).isEqualTo(bstRoot.remove(7).getData());
assertThat(bstRoot.search(8).getData()).isEqualTo(bstRoot.remove(8).getData());
assertThat(bstRoot.search(5).getData()).isEqualTo(bstRoot.remove(5).getData());
}

@Test
@DisplayName("AVL_트리_제거_테스트2")
void AVL_트리_제거_테스트2() {
BinarySearchTreeNode<Integer> bstRoot = new AVLTreeNode<>(1, (Comparator.comparingInt(o -> o)));

bstRoot.insert(3);
bstRoot.insert(4);
bstRoot.insert(5);
bstRoot.insert(7);
bstRoot.insert(8);
bstRoot.insert(9);

// BinaryTreeNode<Integer> rootNode = bstRoot.search(3);
// BinaryTreeNode<Integer> rootNodeLeftSubTree = rootNode.getLeftSubTree();
// BinaryTreeNode<Integer> rootNodeRightSubTree = rootNode.getRightSubTree();
//
// assertThat(rootNode.getData()).isEqualTo(3);
// assertThat(rootNodeLeftSubTree.getData()).isEqualTo(1);
// assertThat(rootNodeRightSubTree.getData()).isEqualTo(7);
// assertThat(rootNodeRightSubTree.getLeftSubTree().getData()).isEqualTo(5);
// assertThat(rootNodeRightSubTree.getRightSubTree().getData()).isEqualTo(8);

assertThat(bstRoot.search(1).getData()).isEqualTo(bstRoot.remove(1).getData());
assertThat(bstRoot.search(3).getData()).isEqualTo(bstRoot.remove(3).getData());
assertThat(bstRoot.search(5).getData()).isEqualTo(bstRoot.remove(5).getData());
assertThat(bstRoot.search(4).getData()).isEqualTo(bstRoot.remove(4).getData());
assertThat(bstRoot.search(7).getData()).isEqualTo(bstRoot.remove(7).getData());
assertThat(bstRoot.search(9).getData()).isEqualTo(bstRoot.remove(9).getData());
assertThat(bstRoot.search(8).getData()).isEqualTo(bstRoot.remove(8).getData());
}
}