๐ฏ ๋ชฉํ :ย ์ด์ง ํ์ ํธ๋ฆฌ๋ฅผ ๊ตฌํํ๋ฉฐ, ๊ท ํ ์กํ ์ด์ง ํ์ ํธ๋ฆฌ๋ฅผ ๊ตฌํ ํ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ ํ์ต
static class Node<Key,Value>{
private Key key;
private Value data;
private Node<Key,Value> left;
private Node<Key,Value> right;
public Node(Key key, Value data, Node<Key, Value> left, Node<Key, Value> right) {
this.key = key;
this.data = data;
this.left = left;
this.right = right;
}
public Key getkey() { return key; }
public void setKey(Key key) { this.key = key; }
public Value getData() { return data; }
public void setData(Value data) { this.data = data; }
// ํด๋น ๋
ธ๋์ ๋ฐ์ดํฐ๋ฅผ ์ถ๋ ฅํ๋ค.
public void print(){ System.out.println(data); }
}
private Node<Key,Value> root;
private Comparator<? super Key> comparator = null;
// root์ ๊ฐ ์ด๊ธฐํ ์์ฑ์
public BsTreeLink (){
root=null;
}
// ๋น์ด์๋ ๋ฃจํธ ํธ๋ฆฌ๋ฅผ ์์ฑํ๊ณ ์ ๋ฌ๋ฐ์ comparator์ ์ ์ํ๋ค.
public BsTreeLink (Comparator<? super Key> c){
this();
comparator = c;
}
private int comp(Key key1, Key key2){
return (comparator == null) ?
// ๊ธฐ๋ณธ ์ ๋ ฌ ๊ธฐ์ค์ด ์๋ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์จ๋ค๋ฉด compareTo ๋ฉ์๋๊ฐ ๊ตฌํ๋๋ค.
((Comparable<Key>)key1).compareTo(key2)
// ์์ฑ์๋ก ํธ๋ฆฌ ์์ฑ์ ํ๋ค๋ฉด, ๋น๊ต์๋ก ๋น๊ต
: comparator.compare(key1,key2);
}
search ์๊ณ ๋ฆฌ์ฆ
public Value search(Key key){
Node<Key, Value> p = root;
while (true){
if(p==null) return null; // ์คํจ
int cond = comp(key,p.getkey()); // key์ p์ ํค๊ฐ ๋น๊ต
if (cond == 0) return p.getData(); // ๊ฐ๋ค๋ฉด Data ๋ฐํ
else if(cond<0) p= p.left; // ์๋ค๋ฉด cond๋ -1์ผ ๊ฒ์ด๊ณ ์ผ์ชฝ ์์๋
ธ๋๋ฅผ ๋ฃจํธ๋ก ๋ค์๊ฒ์
else p=p.right; // ํฌ๋ค๋ฉด cond๋ 1์ผ ๊ฒ์ด๊ณ ์ค๋ฅธ์ชฝ ์์๋
ธ๋๋ฅผ ๋ฃจํธ๋ก ๋ค์๊ฒ์
}
}
add ์๊ณ ๋ฆฌ์ฆ
private void addNode(Node<Key,Value> p,Key key, Value data){
int cond = comp(key,p.getkey());
if(cond==0) return; // ๊ฐ๋ค๋ฉด ์ข
๋ฃ
else if (cond<0) { // ์๋ค๋ฉด ์ผ์ชฝ์ผ๋ก ๊ฐ์ ๋น๊ต
if(p.left==null) p.left = new Node<Key,Value>(key,data,null,null);
else addNode(p.left,key,data);
}else { // ํฌ๋ค๋ฉด ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ์ ๋น๊ต
if(p.right==null) p.right = new Node<Key,Value>(key,data,null,null);
else addNode(p.right,key,data);
}
}
public void add(Key key, Value data){
// ๋ฃจํธ๊ฐ ๋น์ด์๋ค๋ฉด ์๋ก์ด ๋
ธ๋ ์์ฑ
if(root == null) root = new Node<Key,Value>(key,data,null,null);
// ์๋๋ผ๋ฉด addNode ๋ฉ์๋ ํธ์ถํ์ฌ ๋น์ด์๋ ๋
ธ๋์ ํค์ ๋ฐ์ดํฐ ๊ฐ ์ฝ์
else addNode(root,key,data);
}
remove ์๊ณ ๋ฆฌ์ฆ
1. ์์ ๋
ธ๋๊ฐ ์๋ ๋
ธ๋๋ฅผ ์ญ์ ํ๋ ๊ฒฝ์ฐ
1.1 ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ์ด๋ฉด ์ผ์ชฝ ํฌ์ธํฐ๋ฅผ null
1.2 ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ค๋ฅธ์ชฝ์ด๋ฉด ์ค๋ฅธ์ชฝ ํฌ์ธํฐ๋ฅผ null
2.์์ ๋
ธ๋๊ฐ ํ๋์ธ ๋
ธ๋๋ฅผ ์ญ์ ํ๋ ๊ฒฝ์ฐ
2.1 ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ์ด๋ฉด ์ผ์ชฝ ํฌ์ธํฐ๋ฅผ ์ญ์ ํ ๋
ธ๋ ์์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํค๋๋ก ์ ์
2.2 ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ค๋ฅธ์ชฝ์ด๋ฉด ์ค๋ฅธ์ชฝ ํฌ์ธํฐ๋ฅผ ์ญ์ ํ ๋
ธ๋ ์์ ๋
ธ๋๋ฅผ ๊ฐ๋ฅดํค๋๋ก ์ ์
3. ์์ ๋
ธ๋๊ฐ ๋์ธ ๋
ธ๋๋ฅผ ์ญ์ ํ๋ ๊ฒฝ์ฐ
3.1 ์ญ์ ํ ๋
ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์์ ํค๊ฐ์ด ๊ฐ์ฅ ํฐ ๋
ธ๋๋ฅผ ๊ฒ์
3.2 ๊ฒ์ํ ๋
ธ๋์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ ๋
ธ๋๋ก ๋ณต์ฌ
3.3 ๊ฒ์ํ ๋
ธ๋๋ฅผ ์ญ์
3.3.1 3.3์์ ์ญ์ ํ ๋
ธ๋์ ์์์ด ์๋ค๋ฉด 1์ ์์์ ๋ฐ๋ผ ์ญ์
3.3.2 3.3์์ ์ญ์ ํ ๋
ธ๋์ ์์์ด 1๊ฐ๋ง ์๋ค๋ฉด 2์ ์์์ ๋ฐ๋ผ ์ญ์
# ์๋ธ ํธ๋ฆฌ์์ ํค๊ฐ์ด ๊ฐ์ฅ ํฐ ๋
ธ๋๋ฅผ ๊ฒ์ ํ์์๋ ์์์ด ํ๋๊ฑฐ๋ ์๋ ๊ฒฝ์ฐ๋ฐ์ ์๋ค.
public boolean remove(Key key){
Node<Key,Value> p = root; // ํ์์ค์ธ ๋
ธ๋
Node<Key,Value> parent = null; // ํ์์ค์ธ ๋
ธ๋์ ๋ถ๋ชจ ๋
ธ๋
boolean isLeftChild = true; // p๊ฐ ๋ถ๋ชจ์ ์ผ์ชฝ ์์ ๋
ธ๋์ธ์ง ํ์ธ
// ์ญ์ ํ ๋
ธ๋๋ฅผ ํ์
while (true){
if(p==null) return false; // ํ์์ค์ธ ๋
ธ๋๊ฐ ๋น์ด์๋ค๋ฉด ์ญ์ ์คํจ.
int cond = comp(key,p.getkey()); // key์ p์ ํค ๊ฐ์ ๋น๊ต
if(cond==0) break; // ์ฐพ์ผ๋ฉด ๋ฐ๋ณต๋ฌธ ๋น ์ ธ๋๊ฐ.
else {
parent = p;
if(cond<0){
isLeftChild = true;
p = p.left;
} else {
isLeftChild = false;
p= p.right;
}
}
}
// p์ ์ผ์ชฝ ๋
ธ๋๊ฐ ์์๋
if (p.left==null){
if(p==root) root = p.right; // root๋ฅผ ์ญ์ ํ ๋
// ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ผ์ชฝ ์ผ๋
else if(isLeftChild) parent.left = p.right;
// ์ญ์ ํ ๋
ธ๋๊ฐ ๋ถ๋ชจ๋
ธ๋์ ์ค๋ฅธ์ชฝ ์ผ๋
else parent.right = p.right;
// p์ ์์ชฝ ๋
ธ๋๊ฐ ์์๋
} else if (p.right == null) {
if(p==root) root=p.left; // root๋ฅผ ์ญ์ ํ ๋
else if(isLeftChild) parent.left = p.left;
else parent.right = p.left;
} else {
// ์ญ์ ํ ๋
ธ๋์ ์์ชฝ ๋ชจ๋ ๋
ธ๋๋ฅผ ๊ฐ์ง๊ณ ์์๋.
parent = p;
Node<Key,Value> left = p.left;
isLeftChild = true;
// ์ญ์ ํ ๋
ธ๋์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์์ ๊ฐ์ฅ ํฐ ํค ๊ฐ์ ์ฐพ๋๋ค.
while (left.right != null){
parent = left;
left = left.right;
isLeftChild = false;
}
p.key = left.key;
p.data = left.data;
if(isLeftChild) parent.left = left.left;
else parent.right = left.left;
}
return true;
}
์ค์ ์ํ, ์ ์ ์ํ, ํ์ ์ํ๋ฅผ ๊ตฌํํ๊ณ ์ถ๋ ฅํ๋ค.
// ์ค์ ์ํ
private void inorderSubTree(Node node){
if(node != null){
inorderSubTree(node.left);
System.out.println(node.key+" = "+node.data);
inorderSubTree(node.right);
}
}
// ์ ์ ์ํ
private void preOrderSubTree(Node node){
if(node != null){
System.out.println(node.key+" = "+node.data);
preOrderSubTree(node.left);
preOrderSubTree(node.right);
}
}
// ํ์ ์ํ
private void postOrderSubTree(Node node){
if(node != null){
postOrderSubTree(node.left);
postOrderSubTree(node.right);
System.out.println(node.key+" = "+node.data);
}
}
// ํธ๋ฆฌ์ ๋ชจ๋ ๋ฐ์ดํฐ ์ถ๋ ฅ
public void print(){
inorderSubTree(root);
}
public void preOrderPrint(){
preOrderSubTree(root);
}
public void postOrderPrint(){
postOrderSubTree(root);
}