저번학기에 공부할 때부터 많이 헷갈렸었던 AVL트리다.
트리 T의 모든 내부노드 v에 대해 자식들의 좌우 높이 차가 1이 넘지 않는 이진탐색트리이다.
n개의 항목을 저장하는 AVL트리의 높이는 O(logn)
이다.
자꾸 까먹는데, AVL트리를 이진탐색트리와 분리하려하지 말자. AVL의 restructuring을 이해하려면 AVL이 이진탐색트리인것을 잊으면 안 된다.
: 갱신 이후에 높이 균형 속성이 파괴될 수 있으므로 balance check 후 restructuring 진행.
Alg searchAndFixAfterInsertion(w)
// x, y, z 노드 정하기 :)
1. w에서 T의 루트로 향해 올라가다 처음 만나는 불균형 노드를 z라 하자.
2. z의 높은 자식을 y라 하자. {나중에 y가 w의 조상이 된다.}
3. y의 높은 자식을 x라 하자
4. restructure(x, y, z)
5. return
Restructure(x, y, z)
: 회전이라고 불리기도 한다.
이해해보기.
z z z z
/ / \ \
y y y y
/ \ \ /
x x x x
이렇게 네 경우가 있다. 타이핑 너무 귀찮으니까 이제 그림으로 그려야겠다.
중위순회 순서는 오름차순이라는 뜻. 그냥 법이다 법 잊지 말자
개조 시작 ~ 👻
1. z를 루트로 하는 부트리(빨간 거 말고 y랑 연결돼있는 부분)를 b를 루트로 하는 부트리로 대체.
👉🏻 이렇게 하면 가운데에 오는 애가 z 자리로 가는 거 알겠지?
그 다음엔 아까 찾았었던 빨간 부트리들을 a와 c에 붙여준다.
2. T_0와 T_1을 a의 왼쪽, 오른쪽 부트리로 만든다.
3. T_2와 T_3을 c의 왼쪽, 오른쪽 부트리로 만든다.
코드로 구현하면 다음과 같다. 음.. 한 세 번째 보는 거지만 볼 때마다 헷갈려서 적어봤다.
이걸 다시 볼 일이 있을진 모르겠다.
TreeNode* restructure(TreeType* T, TreeNode* x) {
TreeNode* y, * z, * a, * b, * c; // 부모, 부모의 부모
TreeNode* T0, * T1, * T2, * T3;
y = x->parent; printf("y = x->parent 대입\n");
printf("y: %d\n", y->key);
printf("z: %d\n", y->parent->key);
printf("x = y->parent 대입\n");
z = y->parent;
if (z->key < y->key && y->key < x->key) { // z < y < x
a = z;
b = y;
c = x;
T0 = a->left;
T1 = b->left;
T2 = c->left;
T3 = c->right;
} else if (z->key > y->key && y->key > x->key) { // x < y < z
a = x;
b = y;
c = z;
T0 = a->left;
T1 = a->right;
T2 = b->right;
T3 = c->right;
} else if (z->key < x->key && x->key < y->key) { // z < x < y
a = z;
b = x;
c = y;
T0 = a->left;
T1 = b->left;
T2 = b->right;
T3 = c->right;
} else { // y < x < z
a = y;
b = x;
c = z;
T0 = a->left;
T1 = b->left;
T2 = b->right;
T3 = c->right;
}
//3.
if(z == T->root) {
T->root = b;
b->parent = NULL;
} else if (z->parent->left == z) {
z->parent->left = b;
b->parent = z->parent;
} else {
z->parent->right = b;
b->parent = z->parent;
}
// 4.
a->left = T0;
T0->parent = a;
a->right = T1;
T1->parent = a;
a->height = max(T0->height, T1->height) + 1;
// 5.
c->left = T2;
T2->parent = c;
c->right = T3;
T3->parent = c;
c->height = max(T2->height, T3->height) + 1;
// 6.
b->left = a;
a->parent = b;
b->right = c;
c->parent = b;
b->height = max(a->height, c->height) + 1;
return b;
}