31
1010101010100000 0101010101010001 0101010100101010 1010101010100101 DATA STRUCTURES @Override public void add(Node<T> node) { Node pointer = header; while (pointer.next != null) { pointer = pointer.next; } pointer.next = node; size++; } A B H G front rear AVL Tree

[SOPT] 데이터 구조 및 알고리즘 스터디 - #05 : AVL 트리

Embed Size (px)

Citation preview

1 0 1 0 1 0 1 0 1 0 1 0 0 0 0 0

0 1 0 1 0 1 0 1 0 1 0 1 0 0 0 1

0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0

1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1

DATA STRUCTURES

@Override

public void add(Node<T> node) {

Node pointer = header;

while (pointer.next != null) {

pointer = pointer.next;}pointer.next = node;

size++;}

A

B

H

G

front

rearAVL Tree

SHOUT OUR PASSION TOGETHER DATA STRUCTURES INDEX

004

005

006

011

012

020

030

AVL - 개요

AVL - 특징

AVL - 용어

AVL - 요구사항

AVL - 코드분석

AVL - 예제

AVL - 성능분석

TABLE OF CONTENTS

035AVL - 사례

AVL Tree개요 · 성질 · 용어 · 요구 사항 · 코드분석 · 시간 복잡도 · 사례

NO CONTENTStudy - Data Structures

AVL개요

각노드마다왼쪽, 오른쪽부분트리의높이차정보가있음

가장초기에나온균형잡힌 이진탐색트리

부분트리의높이차이가 1보다크지않은성질을가짐

4

1

0 2

0 3

7

5 8

6 9

Study - Data Structures

AVL특징

노드가삽입, 삭제될때회전을통해트리를재구성하여높이균형성질을유지시킨다

이진탐색트리에서의검색시간복잡도는트리의높이과같으므로 O (log n) 임을알수있다

높이균형성질로부터, n 개의원소를갖는 AVL 트리의높이는 log n 이다

삽입과삭제를할때, 원하는노드를찾기위해 2개의경로를필요로하기때문에효율이낮다

Ref. https://ko.wikipedia.org/wiki/AVL_%ED%8A%B8%EB%A6%AC

용어균형치 (Balance factor)- 왼쪽서브 트리의높이 – 오른쪽서브 트리의높이

AVL

Study - Data Structures

AVL용어 - LL 회전

Ref. http://girlsy7.tistory.com/134

Study - Data Structures

AVL용어 - RR 회전

Ref. http://girlsy7.tistory.com/134

Study - Data Structures

AVL용어 - RL 회전

Ref. http://girlsy7.tistory.com/134

Study - Data Structures

AVL용어 - LR 회전

Ref. http://girlsy7.tistory.com/134

Study - Data Structures

AVL요구사항

삽입 · 삭제 : 트리에특정노드를추가하거나삭제

높이계산 : 루트부터리프노드까지의높이를계산

회전구현 : LL, RR, LR, RL

높이조절

출력을위한 Depth 지정및출력

Study - Data Structures

코드분석 - 삽입

AVL

Root Node 여부확인

중복 key 확인

자식 Node를 생성하기 위한작업

부모 key와 비교후 방향선택

public boolean insert(int key) {

if (root == null)root = new Node(null, key, null);

else {

Node<Integer> n = root;Node<Integer> parent;

while (true) {

if (n.key == key)return false;

parent = n;

boolean goLeft = parent.key > key;n = goLeft ? parent.left : parent.right;

if (n == null) {

if (goLeft) parent.left = new Node(null, key, parent);

else parent.right = new Node(null, key, parent);

rebalance(parent);break;

}}

}return true;

}

Study - Data Structures

AVL

Node 생성

코드분석 -삭제

삭제할 Node 검색

Key값비교로 방향선택

자식 Node 분리

삭제할 Node의 자식 Node를 부모 Node에 연결한다

Key값 비교로방향선택

높이조절

public void delete(int delKey) {

if (root == null)return;

Node<Integer> n = root, parent = root, child = root;Node<Integer> delNode = null;

while (child != null) {

parent = n;n = child;child = delKey >= n.key ? n.right : n.left;if (delKey == n.key)

delNode = n;}

if (delNode != null) {

delNode.key = n.key;child = n.left != null ? n.left : n.right;

if (root.key == delKey)root = child;

else {

if (parent.left == n) parent.left = child;else parent.right = child;

rebalance(parent);}

}}

Study - Data Structures

AVL

Balance 설정

양쪽높이의 차이를 -2 미만으로조절

코드분석 -높이조절

양쪽높이의 차이를 2 미만으로 조절

모든트리의 balance를맞춘다.

private void rebalance(Node n) {

setBalance(n);

if (n.balance == -2) {

if (height(n.left.left) >= height(n.left.right))n = rotateRight(n);

elsen = rotateLeftThenRight(n);

} else if (n.balance == 2) {

if (height(n.right.right) >= height(n.right.left))n = rotateLeft(n);

elsen = rotateRightThenLeft(n);

}

if (n.parent != null) rebalance(n.parent);

else root = n;

}

Study - Data Structures

AVL

임의의 b Node를 두고정보를 옮김

Node를 이동시켜 회전한다.

코드분석 -왼쪽회전

Balance를 다시맞춰준다.

최종적으로 b Node 반환

private Node rotateLeft(Node a) {

Node b = a.right;

b.parent = a.parent;a.right = b.left;

if (a.right != null)a.right.parent = a;

b.left = a;a.parent = b;

if (b.parent != null) {

if (b.parent.right == a) b.parent.right = b;

else b.parent.left = b;

}

setBalance(a, b);return b;

}

private Node rotateLeftThenRight(Node n) {

n.left = rotateLeft(n.left);return rotateRight(n);

}

LR 회전

왼쪽을먼저 회전한다음 오른쪽을회전

Study - Data Structures

AVL코드분석 -오른쪽회전

임의의 b Node를 두고정보를 옮김

Node를 이동시켜 회전한다.

Balance를 다시맞춰준다.

최종적으로 b Node 반환

private Node rotateRight(Node a) {

Node b = a.left;

b.parent = a.parent;a.left = b.right;

if (a.left != null)a.left.parent = a;

b.right = a;a.parent = b;

if (b.parent != null) {

if (b.parent.right == a)b.parent.right = b;

else b.parent.left = b;

}

setBalance(a, b);return b;

}

private Node rotateRightThenLeft(Node n) {

n.right = rotateRight(n.right);return rotateLeft(n);

}

RL 회전

오른쪽을먼저 회전한다음 왼쪽을회전

Study - Data Structures

AVL

재귀를통해 높이를계산

코드분석 -높이,밸런스,깊이계산

Balance를 계산

왼쪽과오른쪽 높이의차를 저장

Root depth를 0으로지정

Root의 왼쪽, 오른쪽 Node의 depth를 계산

N의깊이 =부모 Depth + 1로설정

Node n의왼쪽, 오른쪽 Node의 depth를 계산

private int height(Node n) {

if (n == null)return -1;

return 1 + Math.max(height(n.left), height(n.right));}

private void setBalance(Node... nodes) {

for (Node n : nodes)n.balance = height(n.right) - height(n.left);

}

public void caldep() {

root.depth = 0;

caldep(root.left);caldep(root.right);

}

private void caldep(Node n) {

if(n != null){

n.depth = n.parent.depth + 1;

caldep(n.left);caldep(n.right);

}}

Study - Data Structures

AVL

Depth 값인 max과 비교하여 Tree를출력

코드분석 - Tree 출력

Node n의 depth가 max값과같으면 출력

Node n의왼쪽, 오른쪽 Node를탐색

public void printTree(int max){

printTree(root, max);}

private void printTree(Node n, int max){

if(n != null){

if(n.depth == max)System.out.print(n.key + " ");

printTree(n.left, max);printTree(n.right, max);

}}

Study - Data Structures

AVL코드분석

https://github.com/ac9831/AVL-Tree

예제 - 1 ~ 10 입력

AVL

Insert 1 Insert 2 Insert 3

1 1

2

3

1

2

예제 - 1 ~ 10 삽입

AVL

Rebalance Insert 4 Insert 5

1

2

3

4

1

2

31

2

3

4

5

예제 - 1 ~ 10삽입

AVL

Rebalance Rebalance Insert 6

1

2

3

4

5

3번 Node가기준

1

2

3

4

5

1

2

3

4

5

6

AVL

Rebalance Rebalance Rebalance

2번 Node가기준RR회전

1

2

3

4

5

61

2

3

4

5

6 1

2

3

4

5

6

예제 - 1 ~ 10삽입

AVL

Insert 7 Rebalance Insert 8

1

2

3

4

5

6

7 1

2

3

4

5

6

7

5번 Node가기준RR회전

1

2

3

4

5

6

7

8

예제 - 1 ~ 10삽입

AVL

Insert 9 Rebalance Insert 10

5번 Node가기준RR회전

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

1

2

3

4

5

6

7

8

9

10

6번 Node가기준RR회전

예제 - 1 ~ 10삽입

AVL

Rebalance Rebalance Result

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10

예제 - 1 ~ 10삽입

1

2

3

4

5

6

7

8

9

10

AVL

Start Delete node 6 Result

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

7

8

9

10

6 node값을 7로변경한후오른쪽자식 Node를 7 node의자식 node로갱신한다.예제 - 6 삭제

1

2

3

4

5

7

8

9

10

AVL

Start Delete node 8 update

삭제시가장가까운값. 만약 9 node.left에값이있었다면그값이삭제되는 8 node로갱신된다.예제 - 8삭제

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

6

7

8

9

10

1

2

3

4

5

9

9

10

6

7

AVL

Result

1

2

3

4

5

6

7

9

10

예제 - 8 삭제

Study - Data Structures

AVL성능분석

Ref. https://ko.wikipedia.org/wiki/AVL_%ED%8A%B8%EB%A6%AC

메모리사용공간

연산시간

1. 균형이진트리이므로다음식이도출된다.

→ 1번검색, 삽입, 삭제에대해 h 만큼이동 : h = log₂ n

2. 검색, 삽입, 삭제에대해평균﹒최악의경우모두 O (log n)의시간복잡도를갖는다

3. 삽입과삭제시, 검색에소요되는시간 + 상수시간이걸리므로 O (log n)의시간복잡도를갖는다

평균시간복잡도

O (log n)

O (n) : n 개의원소에대하여 n 개의메모리사용

컴퓨터디렉토리 구조 계층구조

Study - Data Structures

사례

AVL