Download Heap and AVL Trees: Understanding Their Differences and Importance in Computer Science and more Lecture notes Algorithms and Programming in PDF only on Docsity!
제11장 힙, AVL 트리
이 장에서는 이진 트리의 특수한 형태인 힙(heap)과 AVL 트리에 대해 살펴본다.
우선순위 큐: 힙(heap)
AVL 트리: 균형 트리
일반적으로 큐는 FIFO 구조를 가진다.
FIFO 큐도 우선순위 큐로 볼 수 있다.
deq O(N) O(1) O(log 2 N)
enq O(1) O(N) O(log 2 N)*
6 장에서 살펴본 바와 같이 일반적으로 큐는 FIFO 구조를 가진다. 하지만 큐에 삽입된 순서
있다. 이런 큐를 우선순위 큐(priority queue)라 한다. 우선순위 큐에서 우선순위는 응용에 따
용을 비교하여 보자. 우선 비정렬 리스트를 이용할 경우에는 enqueue는 O(1)이지만
dequeue는 현재 큐에 저장되는 있는 모든 요소를 서로 비교하여 가장 큰 값을 찾아야 하므
로 O( )이다. 반대로 정렬 리스트를 이용할 경우에는 enqueue할 때 우선순위에 따라 정렬
이 되도록 저장해야 하므로 O(^ ^ )이지만 dequeue의 비용은 O(1)이다. 이진 검색 트리를 이
용하여 우선순위 큐를 구현하면 enqueue와 dequeue 모두 평균적으로 O( )이다. 하지
힙힙(heap)은 이진 트리를 이용하여 우선순위 큐를 구현하는
J
H
D G
B C E
I
F A
J
I
F G
B C D
H
E A
heap
힙(heap)은 우선순위 큐를 구현할 때 널리 사용되는 자료구조로서 다음 두 가지 특성을 만
힙: enqueue
힙에서마지막 레벨에 가장 오른쪽에 추가되어야 한다 enqueue는 완전 이진 트리를 유지하기 위해서는 항상 가장.
P
L
E F
B C A
N
K G
P
L
E F
B C A
N
K G
M
힙: enqueue – 계속
dequeue교체해야 한다와 비슷하게 순서 특성을 만족하도록 부모와 값을. 이런 교체는 트리가 순서 특성을 만족할 때까지
반복되어야 하며, 이런 재조정을 reheapupreheapup이라 한다.
P
L
E F
B C A
N
K G
M
P
M
E L
B C A
N
K G
F
힙에서 enqueue는 모양 순서 특성을 만족하기 위해 마지막 레벨의 가장 오른쪽 단말노드로
새 데이터가 추가되어야 한다. 하지만 dequeue와 마찬가지로 이렇게 함으로써 모양 특성을
만족될 때까지 반복적으로 이루어진다. 이 과정을 reheapup이라 한다. 따라서 마지막 레벨
의 가장 오른쪽 단말노드로 노드를 추가하는 비용이 상수 비용이면 enqueue의 시간복잡도
enqueue와 dequeue의 설명에서 알 수 있듯이 이들 연산의 시간복잡도가 로그시간이 되기
로그시간을 넘지 않아야 한다. 또한 reheapup을 구현하기 위해서는 노드에서 그것의 자식
P
L
E F
B C
N
K G
P L N E F K G B C
부모의 위치 왼쪽 자식의 위치: (index-1)/2: (index2)+ 오른쪽 자식의 위치: (index2)+
색인이 i인 항에 위치하면 그것의 부모는 색인이 (i-1)/2인 항에 위치하며, 그것의 왼쪽 자식
노드는 색인이 (i2)+1인 항에, 오른쪽 자식 노드는 색인이 (i2)+2인 노드에 위치한다. 이렇
Dequeue
M
E L
B C A
N
K G
F
hole nextHole
public Object deq() throws QueueUnderflowException{if(isEmpty()) throw new QueueUnderflowException(“…”); Comparable toMove = (Comparable)elements[lastIndex];Object tmp = elements[0]; lastIndexreheapDown(toMove);--; } return tmp; private void reheapDown(Comparable item){int hole = 0; int nextHole;nextHole = findNextHole(hole, item); while(nextHole != hole){elements[hole] = elements[nextHole]; hole = nextHole;nextHole = findNextHole(hole, item); }elements[hole] = item; }
Dequeue private int findNextHole(int hole, Comparable item){int left = hole2+1;int right = hole2+2;
Comparable leftChild = null;// hole이 자식이 없는 경우 if(left>lastIndex){return hole; }// hole이 왼쪽 자식밖에는 없는 경우 else if(left==lastIndex){if(item.compareTo(elements[left])>0) return hole; } else return left; // else{ hole이 왼쪽, 오른쪽 자식이 모두 있는 경우 leftChild = (Comparable)elements[left];if(leftChild.compareTo(elements[right])>0){ if(item.compareTo(leftChild)>0) return hole;else return left; }else{ if(item.compareTo(elements[right])>0) return hole;else return right; } } }
dequeue는 enqueue보다 조금 더 복잡하다. 우선 lastIndex 정보를 이용하여 트리의 가장
삭제는 lastIndex 값을 하나 감소하면 된다. 그 다음 순서 특성이 만족되도록 reheapdown을
해야 한다. reheapup은 한쪽 방향으로 최대 루트까지 올라가면 되지만 reheapdown은 현재
교체되어야 한다. 어떤 자식과 교체할지는 findNextHole 메소드를 통해 결정한다.
힙 VS. 다른 우선순위 큐 구현
O(log 2 N)
O(log 2 N)
deq O(log 2 N) O(1) O(N)
enq O(log 2 N) O(N) O(N)
유지하므로 enqueue와 dequeue 연산의 시간복잡도는 로그 시간이다.
11.4. AVL 트리
해 트리의 균형을 주기적으로 맞출 수 있지만 균형을 맞추는 비용이 매우 비싸다. AVL 트
AVL 트리(균형트리)
AVL(AdelsonAVL(Adelson--VelskiiVelskii and Landis)and Landis) 트리트리: 각 노드의 왼쪽 서브트리의
이진 트리의 한 노드가 AVL 성질을 만족하는지 검사하는 방법
두 경로의 차이를 균형균형 인수인수(balance factor)라 한다.
AVL Tree non AVL Tree
AVL 트리는 각 노드의 왼쪽 서브트리의 높이와 오른쪽 서브트리의 높이의 차이가 1 이하인
이진 검색 트리를 말하며, 러시아 수학자 Adelson-Velskii와 Landis에 의해 고안되었다. 이진
트리의 한 노드가 AVL 성질을 만족하는지 검사하기 위해서는 그 노드의 왼쪽 서브 트리의
AVL 트리: 삽입 – 계속
부분 트리를 재조정해야 하는 노드위치는 다음 네 가지로 분류할 수 있다 x 를 기준으로 삽입된 노드의.
LL: x 의 왼쪽 자식의 왼쪽 부분 트리에 삽입된 경우
RR: x 의 오른쪽 자식의 오른쪽 부분 트리에 삽입된 경우
LR: x 의 왼쪽 자식의 오른쪽 부분 트리에 삽입된 경우
RL: x 의 오른쪽 자식의 왼쪽 부분 트리에 삽입된 경우
A
B
C
A
B
C
A -
B
C
A
B
C
LL RR
LR RL
크게 LL, RR, LR, RL 네 가지 경우로 분류할 수 있다.
LL, RR 회전
트리의 균형은 노드들을 회전회전(rotate)하여 맞춘다.
LL과 RR의 경우에는 단일 회전으로 균형을 맞출 수 있지만
LR과 RL의 경우에는 이중 회전을 해야 균형을 맞출 수 있다.
A
B
B
A
T2 T
A
B
T1 T1 T
B
A
T
LL Rotate (^) RR Rotate
T1 T2 T3^ T1^ T2^ T
음으로 균형인수가 -2 또는 2 가 된 노드의 위치에 따라 LL, RR, LR, RL 회전을 한다. 삽입
의 기준 노드라 한다. 이 때 LL과 RR은 단일 회전으로 균형을 맞출 수 있지만 LR과 RL은
두 번 회전이 필요하므로 이중 회전이 필요하다고 말한다. LL과 RR은 기준 노드의 자식 중
LR 회전
A
B
C
B A
C
A
B
C
T1 T2 T
T
C
B A
T
A
B
C
T1 T2 T
T
C
B A
T1 T2 T3 T
T1 T2 T
LR 회전은 처음으로 균형인수가 2 가 된 노드를 포함하여 그 노드부터 삽입된 노드까지 경
로에 있는 가장 가까운 두 개의 후손 노드들이 회전에 참여하게 된다. 기준 노드를 A 노드
라 하고 두 개의 후손 노드들을 차례대로 B와 C 노드라 하면, 이 부분 트리를 재조정하였
을 때 루트는 C가 되고, C의 왼쪽 자식은 B, 오른쪽 자식은 A 노드가 된다. 또한 C 노드의
왼쪽 부분 트리는 B 노드의 오른쪽 부분 트리가 되고, C의 오른쪽 부분 트리 A의 왼쪽 부
RL 회전
A
B
C
A B
C
A
B
C
C
A B
T1 T2 T3 T
A
B
C
C
A B
T
T2 T
T1 T
T2 T
T1 T
T1 T2 T
RL 회전은 LR 회전과 마찬가지로 처음으로 균형인수가 -2가 된 노드를 포함하여 그 노드부
다. 기준 노드를 A 노드라 하고 두 개의 후손 노드들을 차례대로 B와 C 노드라 하면, 이
부분 트리를 재조정하였을 때 이 회전 역시 C가 루트가 되고, C의 왼쪽 자식은 A, 오른쪽
자식은 B 노드가 된다. 또한 C 노드의 왼쪽 부분트리는 A 노드의 오른쪽 부분 트리가 되
고, C의 오른쪽 부분 트리 B의 왼쪽 부분 트리가 된다.
AVL 트리: 삭제
삭제도 삽입과 마찬가지로 AVL 트리의 성질을 위배할 수 있다.
하여도 여전히 트리가 AVL 트리의 성질을 위배할 수 있다.
AVL 트리에서 삭제도 삽입과 마찬가지로 먼저 이진 검색 트리에서 삭제를 수행한다. 그 다
AVL 트리: 삭제 – 고려사항 1
경우 2.^0
에는 트리가 AVL 트리의 성질을 만족하고 있으므로 트리에 있는 모든 노드의 균형인수는
AVL 트리: 삭제 – 고려사항 2
LL
RR
AVL 트리에서 삭제는 기존 삽입에서 보았던 LL, LR, RR, RL 네 가지 외에 특이한 두 가지
경우가 존재한다. 보통 삽입에서 LL은 A 노드의 균형인수가 2 이고, B 노드의 균형인수가 1
이다. 하지만 삭제의 경우 이 슬라이드에서 보여주듯이 A 노드의 균형인수가 2 이고, B 노드
의 균형인수가 0 인 경우가 존재한다. 하지만 이 경우도 LL 회전을 통해 균형을 맞출 수 있
다. 또한 삽입에서 검토되었던 RR은 A 노드의 균형인수가 -2이고, B 노드의 균형인수가 -
이다. 하지만 삭제의 경우 이 슬라이드에서 보여주듯이 A 노드의 균형인수가 -2이고, B 노
드의 균형인수가 0 인 경우가 존재한다. 이 경우도 RL 회전을 통해 균형을 맞출 수 있다.
AVL 트리: 삭제 예 – 계속
AVL 트리 분석
전체: W (N) = O(N)
찾기 처리:: TW (N) = O(log(N) = O(log 2 N) 균형: W (N) = O(log^22 N) N 전체: W (N) = O(log 2 N)
전체: W (N) = O(N)
전체: W (N) = O(N)
검색 전체: T (N) = O(log 2 N)
찾기 처리:: TT (N) = O(log(N) = O(1) 2 N) 균형 전체:: WW (N) = O(log(N) = O(log 2 N) 2 N)
AVL 트리
즉저렴하면서 검색은 항상, AVL 트리는 일반 이진 검색 트리와 달리 삽입과 삭제의 연산 비용도 O(log2N)인 트리이다.