AVL ํธ๋ฆฌ๋ Balanced Binary Search Tree์ด๋ค. AVL ํธ๋ฆฌ๋ ๊ฐ๊ฐ ๋
ธ๋๋ง๋ค ์ผ์ชฝ, ์ค๋ฅธ์กฑ ์๋ธํธ๋ฆฌ์ ๋์ด ์ฐจ์ด์ ๋ํ ์ ๋ณด๋ฅผ๊ฐ์ง๊ณ ์๋ธํธ๋ฆฌ์ ๋์ด ์ฐจ์ด๊ฐ 1๋ณด๋ค ํฌ์ง์๋ค๋ ์ฑ์ง์ ๊ฐ์ง๋ค.(์ํคํผ๋์ )
์ฆ, ์์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด ์ฐจ์ด๊ฐ 1์ดํ์ด๋ค.
๊ท ํ์กํ AVL ํธ๋ฆฌ๋ n๊ฐ์ ์์๊ฐ ์์ ๋ O(logn)์ ์๊ฐ๋ณต์ก๋๋ก ๊ฒ์, ์ฝ์
, ์ญ์ ๋ฅผ ํ ์ ์๋ค.
์๊ฐ ๋ณต์ก๋
Rotation
ํธ๋ฆฌ์ ์ฌ๊ตฌ์ฑ ์์
์ Rotation(ํ์ )์ด๋ผ๊ณ ํ๋ค.
LL
Copy z y
/ \ / \
y T4 Right Rotate (z) x z
/ \ - - - - - - - - -> / \ / \
x T3 T1 T2 T3 T4
/ \
T1 T2
y๋ z์ ์ผ์ชฝ ์์, x๋ y์ ์ผ์ชฝ ์์์ด๋ค. ์ด๋ T1, T2, T3, T4๋ ๊ฐ๊ฐ์ ์๋ธํธ๋ฆฌ์ด๋ค.
z์ ์ค๋ฅธ์กฑ ์์๊ณผ ์ผ์ชฝ ์์์ด ๋ถ๊ท ํํ๋ฏ๋ก right Rotation ํ๋ฒ์ผ๋ก ๊ท ํ์ ์ก์์ค ์ ์๋ค.
Copy if (bal > 1 && key < node -> left -> key) return right_rotate (node);
LR
Copy z z x
/ \ / \ / \
y T4 Left Rotate (y) x T4 Right Rotate(z) y z
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
T1 x y T3 T1 T2 T3 T4
/ \ / \
T2 T3 T1 T2
y๋ z์ ์ผ์ชฝ ์์, x๋ y์ ์ค๋ฅธ์ชฝ ์์์ด๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ์๋ ํ์ ์ ๋๋ฒ์์ผ์ค์ผํ๋ค. ์ฐ์ y๋ฅผ ์ผ์ชฝ ํ์ ์ ํ๋ฒ ์์ผ์ฃผ๊ณ z๋ฅผ ์ค๋ฅธ์ชฝ ํ์ ์์ผ์ฃผ๋ฉด ๊ท ํ์ด ์กํ๊ฒ ๋๋ค.
Copy if (bal > 1 && key > node -> left -> key){
node -> left = left_rotate( node -> left) ;
return right_rotate(node) ;
}
RR
Copy z y
/ \ / \
T1 y Left Rotate(z) z x
/ \ - - - - - - - -> / \ / \
T2 x T1 T2 T3 T4
/ \
T3 T4
y๋ z์ ์ค๋ฅธ์ชฝ ์์์ด๊ณ , x๋ y์ ์ค๋ฅธ์ชฝ ์์์ด๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ๋ LL๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋ฒ์ rotation์ผ๋ก ๊ท ํ์ ์ก์ ์ ์๋ค.
Copy if (bal < - 1 && key > node -> right -> key) return left_rotate (node);
RL
Copy z z x
/ \ / \ / \
T1 y Right Rotate (y) T1 x Left Rotate(z) z y
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
x T4 T2 y T1 T2 T3 T4
/ \ / \
T2 T3 T3 T4
y๋ z์ ์ค๋ฅธ์ชฝ์์, x๋ y์ ์ผ์ชฝ ์์์ด๋ค .์ด๋ฌํ ๊ฒฝ์ฐ๋ ์์ LR๊ณผ ์ ๋ฐ๋์ธ ๊ฒฝ์ฐ์ด๋ค. ์ด ๋๋ ์ค๋ฅธ์ชฝ ํ์ ํ ์ผ์ชฝ ํ์ ์ ํ๋ฉด ๊ท ํ์ ๋ง์ถ ์ ์๋ค.
Copy if (bal < - 1 && key < node -> right -> key){
node -> right = right_rotate( node -> right) ;
return left_rotate(node) ;
}
๊ตฌํ
Copy typedef struct node{
int key;
struct node * left , * right;
int height; // ๋์ด
}Node;
Node * new_node ( int key){
Node * new = (Node * ) malloc( sizeof (Node)) ;
new -> key = key;
new -> height = 0 ; //์๋ก์ด ๋
ธ๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋จ๋ง ๋
ธ๋์ height๋ฅผ ๊ฐ์ง๋ค.
new -> left = new -> right = NULL ;
return new;
}
height
Copy int height (Node * node){
if (node == NULL ) return - 1 ;
return node -> height;
}
Right Rotation
Copy /*
z y(l)
/ \ / \
y T4 Right Rotate (z) x z(node)
/ \ - - - - - - - - -> / \ / \
x T3 T1 T2 T3(r) T4
/ \
T1 T2
*/
Node * right_rotate (Node * node){
Node * l = node -> left;
Node * r = l -> right;
l -> right = node;
node -> left = r;
node -> height = 1 + MAX(height( node -> left) , height( node -> right)) ;
l -> height = 1 + MAX(height( l -> left) , height( l -> right)) ;
return l;
}
Left Rotation
Copy /*
z y(r)
/ \ / \
T1 y Left Rotate(z) z(node) x
/ \ - - - - - - - -> / \ / \
T2 x T1 T2(l) T3 T4
/ \
T3 T4
*/
Node * left_rotate (Node * node){
Node * r = node -> right;
Node * l = r -> left;
r -> left = node;
node -> right = l;
node -> height = 1 + MAX(height( node -> left) , height( node -> right)) ;
r -> height = 1 + MAX(height( r -> left) , height( r -> right)) ;
return r;
}
balance
Copy int balance (Node * node){
if (node == NULL ) return 0 ;
// ์์ชฝ ์๋ธํธ๋ฆฌ์ ๋์ด๋ฅผ ๋น๊ตํ๋ค.
return height( node -> left) - height( node -> right) ;
}
์ฝ์
์์ Rotation์ ์ด์ฉํด์ ์ฝ์
์ ๊ตฌํํ ์ ์๋ค.
์ฐ์ BST์ ์ฝ์
๊ณผ ๊ฐ์ด ์ฝ์
ํ๋ค.
ํ์ฌ์ height๊ฐ์ updateํด์ค๋ค.
balanceํ์ง ํ์ธํ๋ค.(-1๋ฏธ๋ง 1์ด๊ณผ ๋ถ๊ท ํ)
๋ถ๊ท ํํ๋ค๋ฉด LL, LR, RR, RL ์ ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ๋ง๊ฒ rotationํด์ค๋ค.
Copy Node * insert (Node * node , int key){
// 1. ๋จผ์ Binary Search Tree์ ์ฝ์
๊ณผ ๊ฐ์ด ์ฝ์
ํ๋ค.
if (node == NULL )
return ( new_node(key) );
if (key < node -> key) node -> left = insert( node -> left , key) ;
else if (key > node -> key) node -> right = insert( node -> right , key) ;
else return node; //๊ฐ์ด ๊ฐ์ ๊ฒฝ์ฐ์๋ BST์ ์ฝ์
๊ณผ ๊ฐ์ง ์๊ณ ๋ฐ๋ก ๋ฆฌํดํด์ค๋ค.
// 2. height๊ฐ์ ๋ณ๊ฒฝํด์ค๋ค.
node -> height = 1 + MAX(height( node -> left) , height( node -> right)) ;
// 3. balanceํ์ง ํ์ธ์ ํ๋ค.(-1๋ฏธ๋ง 1์ด๊ณผ๋ฉด ๋ถ๊ท ํ)
int bal = balance(node) ;
// 4. ๋ถ๊ท ํํ ๊ฒฝ์ฐ์ rotation!
// LL
if (bal > 1 && key < node -> left -> key) return right_rotate(node) ;
// RR
if (bal < - 1 && key > node -> right -> key) return left_rotate(node) ;
// LR ๋๋ฒํ์ (left->right)
if (bal > 1 && key > node -> left -> key){
node -> left = left_rotate( node -> left) ;
return right_rotate(node) ;
}
// RL
if (bal < - 1 && key < node -> right -> key){
node -> right = right_rotate( node -> right) ;
return left_rotate(node) ;
}
return node;
}
์ญ์
์ฐ์ BST์ ์ญ์ ์ ๊ฐ์ด ์ญ์ ํ๋ค.
ํ์ฌ ๋
ธ๋๋ ๋ฐ๋์ ์ญ์ ๋
ธ๋์ ์กฐ์๋
ธ๋ ์ค ํ๋์ฌ์ผํ๋ค.
ํ์ฌ์ height๊ฐ์ updateํด์ค๋ค.
balanceํ์ง ํ์ธํ๋ค.(-1๋ฏธ๋ง 1์ด๊ณผ ๋ถ๊ท ํ)
๋ถ๊ท ํํ๋ค๋ฉด LL, LR, RR, RL ์ ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ๋ง๊ฒ rotationํด์ค๋ค.
Copy Node * delete (Node * root , int key){
Node * tmp;
// 1. BST ์ญ์
if (root == NULL ) return root;
if ( key < root -> key ) root -> left = delete( root -> left , key) ;
else if ( key > root -> key ) root -> right = delete( root -> right , key) ;
else { // ํค๊ฐ์ด ๊ฐ์ผ๋ฉด ๊ทธ ๋
ธ๋๋ฅผ ์ญ์
if ( root -> left == NULL || root -> right == NULL ){
if ( root -> left != NULL )tmp = root -> left;
else tmp = root -> right;
// ์์์ด ์๋ ๊ฒฝ์ฐ
if (tmp == NULL ){
tmp = root;
root = NULL ;
}
else * root = * tmp; // ์์์ด ํ๊ฐ์ธ ๊ฒฝ์ฐ
free(tmp) ;
} else { //์์์ด ๋๊ฐ์ธ ๊ฒฝ์ฐ
tmp = min( root -> right) ;
root -> key = tmp -> key;
root -> right = delete( root -> right , tmp -> key) ;
}
}
// ์ญ์ ํ์ root๊ฐ NULL์ธ๊ฒฝ์ฐ
if (root == NULL ) return root;
// ํ์ฌ height๋ฅผ updateํด์ค๋ค.
root -> height = 1 + MAX(height( root -> left) , height( root -> right)) ;
// balance ๊ฐ์ ๊ฐ์ ธ์จ๋ค.
int bal = balance(root) ;
// ๋ถ๊ท์นํ ๊ฒฝ์ฐ
// LL
if (bal > 1 && balance( root -> left) >= 0 )
return right_rotate(root) ;
// LR
if (bal > 1 && balance( root -> left) < 0 ){
root -> left = left_rotate( root -> left) ;
return right_rotate(root) ;
}
// RR
if (bal < - 1 && balance( root -> right) <= 0 )
return left_rotate(root) ;
// RL
if (bal < - 1 && balance( root -> right) > 0 ){
root -> right = right_rotate( root -> right) ;
return left_rotate(root) ;
}
return root;
}