데이터가 위치하는 규칙이 추가된 트리
이다.작은 데이터는 왼쪽
, 큰 데이터는 오른쪽에
위치하도록 한다.루트 노드 부터 대소 비교
로 데이터 저장 위치를 정한다.리프 노드의 아래
자식노드로 추가된다.루트 노드 부터 대소 비교
로 데이터 저장 위치를 정한다.
1. 삭제할 노드(8)의 왼쪽 서브 트리에서 가장 큰 노드(7) 선택
2. 삭제할 노드의 오른쪽 서브 트리에서 가장 작은 노드 선택
class Node {
public int key; // 노드의 값
public Node left; // 왼쪽 자식 노드
public Node right; // 오른쪽 자식 노드
Node(int key) {
this.key = key;
}
}
class BinarySearchTree {
Node head; // 루트
BinarySearchTree(int key) {
head = new Node(key);
}
}
class BinarySearchTree {
Node head; // 루트
BinarySearchTree(int key) {
head = new Node(key);
}
public void addNode(int key) {
if (head == null) {
head = new Node(key, null, null);
return;
}
Node cur = head;
while (true) {
Node pre = cur;
if (key < cur.key) {
cur = cur.left;
if (cur == null) { // 리프노드
pre.left = new Node(key, null, null);
break;
}
} else {
cur = cur.right;
if (cur == null) { // 리프노드
pre.right = new Node(key, null, null);
break;
}
}
}
}
}
public void removeNode(int key) { // 삭제 하려는 값
// 임시 변수들
Node parent = null;
Node successor = null;
Node predecessor = null;
Node child = null;
// 삭제하려는 값 찾기
Node cur = this.head;
while (cur != null) {
if (key == cur.key) {
break;
}
parent = cur; // 부모노드 저장해 두기
if (key < cur.key) {
cur = cur.left;
} else {
cur = cur.right;
}
}
if (cur == null) {
System.out.println("key에 해당하는 노드가 없습니다.");
return;
}
// 리프 노드인 경우
if (cur.left == null && cur.right == null) {
if (parent == null) { // 노드가 하나밖에 없는 경우
this.head = null;
} else {
if (cur == parent.left) {
parent.left = null; // 삭제
} else {
parent.right = null;
}
}
// 자식 노드가 하나인 경우
} else if (cur.left != null && cur.right == null || cur.left == null && cur.right != null) {
if (cur.left != null) {
child = cur.left;
} else {
child = cur.right;
}
if (parent == null) { // 노드가 하나밖에 없는 경우
this.head = child;
} else {
if (parent.left == cur) {
parent.left = child; // 왼쪽 삭제
} else {
parent.right = child;
}
}
// 자식 노드가 둘인 경우
} else {
predecessor = cur; // successor 부모
successor = cur.left; // 좌측 서브트리에서 가장 큰 노드 저쟝용
while (successor.right != null) {
predecessor = successor;
successor = successor.right;
}
predecessor.right = successor.left; // **
successor.left = cur.left;
successor.right = cur.right;
if (parent == null) {
this.head = successor;
} else {
if (parent.left == cur) {
parent.left = successor;
} else {
parent.right = successor;
}
}
}
}
트리 자료구조의 특징과 동작방식에 대해 공부할 수 있는 기회였다. 자바 코드로 구현함으로써 동작 방식에 대해 더 고민해 볼 수 있었다.