[sopt] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리,...
TRANSCRIPT
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++;}
Tree · Binary Tree · Binary Search Tree · 우선순위큐
A
B
H
G
front
rear
TABLE OF CONTENTS
SHOUT OUR PASSION TOGETHER DATA STRUCTURES INDEX
004
005
019
021
024
027
046
047
051
053
055
066
069
Tree - 개요
Tree - 용어
Binary Tree - 개요
Binary Tree - 성질 / 종류
Binary Tree - 구현
Binary Tree - 순회
Binary Search Tree - 개요
Binary Search Tree – 코드 분석
Binary Search Tree – 성능 분석
우선순위큐 - 개요
우선순위큐 - 힙정렬
우선순위큐 - 코드분석
우선순위큐 - 성능분석
Tree개요 · 용어
Tree개요
Study - Data Structures
아래로내려가면서확장되는트리형태의자료구조
요소들간에 1 : n 계층관계를갖는비선형자료구조
Study - Data Structures
Tree용어
A
B C D
E F GH
I
Study - Data Structures
Tree용어
노드 (Node)
- 트리의 구성요소 (A, B, C, D, E, F, G, H, I)
Study - Data Structures
Tree용어
간선 (Edge)
- 노드를 연결하는선
Study - Data Structures
Tree용어 형제노드 (Sibling Node)
- 같은 부모노드의자식 노드들
Study - Data Structures
Tree용어
조상노드 (Ancestor Node)
- 단말노드에서 간선을따라 루트노드까지이르는경로에 있는모든 노드들
Study - Data Structures
Tree용어
서브트리 (Subtree)
- 부모노드와 연결된간선을 끊었을때생성되는 트리- 각노드는 자식노드 개수만큼의서브트리를 가짐
Study - Data Structures
Tree용어
루트노드 (Root Node)
- 부모가없는 노드 (A)
Study - Data Structures
Tree용어
단말노드 (Terminal Node)
- 자식이없는 노드 (E, F, G, H, I)- 리프 (Leaf) 노드
Study - Data Structures
Tree용어
비단말노드 (Nonterminal Node)
- 적어도하나의 자식을가지는 노드
Study - Data Structures
Tree용어
트리의레벨 (Level)
- 트리의각 층의번호
- 루트 노드의레벨은 1- 한 층내려갈때마다 1씩증가
Study - Data Structures
Tree용어
트리의높이 (Height)
- 트리가가지고 있는최대 레벨
Study - Data Structures
Tree용어
차수 (Dregree)
- 노드의차수 : 노드에연결된자식 노드의개수( 단말 노드의차수 = 0 )
- 트리의차수 : 노드의차수중 가장큰값
Study - Data Structures
Tree용어
포리스트 (Forest)
- 서브트리의 집합
예) 노드 A를 제거하면, 각각노드 B, C, D를루트로하는서브트리가 생기고, 이들의 집합은포리스트가 됨
Binary Tree개요 · 성질 · 종류 · 순회 · 코드
Binary Tree개요
Study - Data Structures
트리의노드구조를일정하게정의하여구현과연산이쉬움
모든노드가 0개이상 2개이하의서브트리를가지는트리
Study - Data Structures
Binary Tree개요
왼쪽서브트리 : 이진트리
오른쪽서브트리 : 이진트리
Binary Tree성질
Study - Data Structures
n 개의노드를가지는이진트리의높이는최소 log ₂ n, 최대 n 이다
높이가 h 인이진트리가가질수있는노드의갯수는최대 h 개이다
n 개의노드를가진이진트리는항상 (n-1) 개의간선을가진다
Study - Data Structures
Binary Tree종류 –포화이진트리(Full Binary Tree)
루트를 1번으로 (2^h-1)까지정해진위치번호를가짐
모든레벨에노드의차수가 2로차있는이진트리
높이가 h일때, 최대노드개수를가진이진트리
왼쪽에서오른쪽으로번호를붙임
Study - Data Structures
Binary Tree종류 –완전이진트리(Complete Binary Tree)
레벨 h 에서는왼쪽부터순서대로채워지는이진트리
레벨 1부터 h-1까지의노드가모두채워져있는트리
Study - Data Structures
Binary Tree구현 –배열표현법
A
B
C
D
E
Index
0
1
2
3
4
5
6
7
8
B
A
C
D E
B
A
C
D
A
B
C
D
Index
0
1
2
3
4
5
6
7
8
각노드에번호를붙여그번호를배열인덱스로삼아배열에데이터를저장하는방법
모든이진트리를포화이진트리로가정
Study - Data Structures
Binary Tree구현 –배열표현법
A
B
C
D
E
Index
0
1
2
3
4
5
6
7
8
B
A
C
D E
노드 i의왼쪽자식노드 인텍스 = 2i
노드 i의부모노드인텍스 = i/2
노드 i의오른쪽자식노드 인텍스 = 2i+1
1
2 3
4 5
Study - Data Structures
Binary Tree구현 –링크표현법
B
A
C
D E
B
A
C
D
포인터를이용해부모노드가자식노드를가리키게하는방법
A
B C
D E
A
B
C
D
Study - Data Structures
Binary Tree이진트리의순회
노드의접근순서에따라세가지방법이존재 : 특정노드와자식노드의순서를고려
트리의모든노드들을체계적으로방문하여각노드가가지고있는데이터를목적에맞게처리
전위순회 (Preorder Traversal) : VLR
중위순회 (Inorder Traversal) : LVR
후위순회 (Postorder Traversal) : LRV
Study - Data Structures
Binary Tree이진트리의순회 –전위순회
루트를 먼저 방문
Study - Data Structures
Binary Tree이진트리의순회 –전위순회
왼쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –전위순회
오른쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –전위순회
1
2
3 4
5
6 7
Study - Data Structures
Binary Tree이진트리의순회 –중위순회
왼쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –중위순회
루트 노드를 방문
Study - Data Structures
Binary Tree이진트리의순회 –중위순회
오른쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –중위순회
4
2
1 3
6
5 7
Study - Data Structures
Binary Tree이진트리의순회 –후위순회
왼쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –후위순회
오른쪽 서브 트리 방문
Study - Data Structures
Binary Tree이진트리의순회 –후위순회
루트 노드를 방문
Study - Data Structures
Binary Tree이진트리의순회 –후위순회
7
3
1 2
6
4 5
Study - Data Structures
Binary Tree이진트리의순회 –레벨순회
각노드를레벨순으로검사하는순회방법
동일레벨인 경우좌에서 우로,위에서부터 아래로순회
큐를사용하여 트리순회를 구현할수있다
Study - Data Structures
Binary Tree이진트순회코드분석
private void inorder(Node r){
if (r != null){
inorder(r.getLeft());System.out.print(r.getData().id +" ");inorder(r.getRight());
}}
private void preorder(Node r){
if (r != null){
System.out.print(r.getData().id +" ");preorder(r.getLeft());preorder(r.getRight());
}}
private void postorder(Node r){
if (r != null){
postorder(r.getLeft());postorder(r.getRight());System.out.print(r.getData().id +" ");
}}
중위순회
전위순회
후위순회
Study - Data Structures
산술식을 트리형태로 표현한것
Binary Tree순회응용 –수식트리
a x
b c
-
중위순회 : a - b × c
후위순회 : :a b c × -
전위순회 : - a × b c
Study - Data Structures
산술식을 트리형태로 표현한것
Binary Tree순회응용 –수식트리
a x
b c
-
중위순회 : a - b × c
후위순회 : :a b c × -
전위순회 : - a × b c
수식트리의계산후위순회사용
구조화된문서 출력 폴더용량 계산
Study - Data Structures
Binary Tree사례
Binary Search Tree개요 · 코드분석 · 성능 분석
Study - Data Structures
Binary Search Tree개요 - 이진트리에탐색조건을추가한자료구조
오른쪽서브트리에있는원소의키들은그루트의키보다큼
왼쪽서브트리에있는원소의키들은그루트의키보다작음
모든요소는서로다른유일한키를가진다는가정을함
왼쪽서브트리와오른쪽서브트리또한이진탐색트리의성격을띔
Study - Data Structures
코드분석 - 삽입
class BST<T extends Data>{
private Node root;public BST() { root = null; }
public boolean isEmpty() {return root == null; }
public void insert(T data) {
root = insert(root, data); }
private Node insert(Node node, T data) {
if (node == null)node = new Node(data);
else {
if (data.compareTo(node.getData()) <0 )node.left = insert(node.left, data);
elsenode.right = insert(node.right, data);
}
return node;}
}
Binary Search Tree
트리의 root 초기화
삽입된노드를 자식으로가지는 루트노드를리턴
삽입될위치를 찾아서노드를 삽입
Study - Data Structures
public void delete(T data) {
if (isEmpty()) {System.out.println("Tree Empty");return;
}
Node p = root, p2 = null;
while (p != null && p.getData().compareTo(data) != 0) {
p2 = p;
if (data.compareTo(p.getData()) < 0) p = p.getLeft();else p = p.getRight();
}
if (p == null) {System.out.println(data + " is not present");return;
}if (p.getLeft() == null && p.getRight() == null) {
if (p2 != null) {if (p2.getLeft() == p) p2.setLeft(null);else p2.setRight(null);
} else root = null;
}
…
코드분석 - 삭제
Binary Search Tree
노드설정
data를 갖는노드 p 탐색
찾는키가 없는경우
삭제할노드의 단말노드 차수가 0인경우
부모의자식 필드를 NULL로 설정
Study - Data Structures
…
else if (p.getLeft() == null || p.getRight() == null) {
Node c = p.getLeft() == null ?p.getRight() : p.getLeft();
if (p2 != null) {
if (p2.getLeft() == p) p2.setLeft(c);else p2.setRight(c);
} else
root = c;}else if (p.getLeft() != null && p.getRight() != null) {
Node q2 = p;Node q = p.getRight();
while (q.getLeft() != null) {
q2 = q;q = q.getLeft();
}
if(q2.getLeft() == q) q2.setLeft(q.getRight());else q2.setRight(q.getLeft());
p.setData(q.getData());}
}
차수가 1인노드의 삭제
c : 자식노드
차수가 2인노드의 삭제
오른쪽서브 트리에서후계자검색
후계자찾아 왼쪽으로이동
후계자(q)의부모와자식을 연결
코드분석 - 삭제
Binary Search Tree
후계자키 값을현재 노드에복사
부모의삭제 : 자식필드를 c로 설정
Study - Data Structures
코드분석 - 탐색
Binary Search Tree
public boolean search(T val) {
return search(root, val);}
private boolean search(Node root, T data) {
boolean found = false;
Node pp;Node p = root;
while ((p != null) && !found) {pp = p;
if (data.compareTo(p.getData()) < 0)p = pp.getLeft();
else if (data.compareTo(p.getData()) > 0)p = pp.getRight();
else {
found = true;break;
}}
return found;}
Binary Search Tree성능분석
Study - Data Structures
기본
검색, 삽입, 삭제등의연산에대한시간복잡도는트리의높이 h에비례
연산시간
평균시간복잡도
O (log n)
1. 최선의경우 : 이진트리가균형적으로생성되어있는경우에해당
→ h = log n
2. 최악의경우 : 트리를구성하는요소가한쪽으로치우쳐진경사이진트리
→ h = n
우선순위큐개요 · 사례 · 힙 정렬 · 코드분석 · 성능 분석
Study - Data Structures
우선순위큐개요
IN OUT
1 2 3우선순위를가진항목들을저장하는큐
우선순위가높은데이터가먼저나가게된다
Study - Data Structures
우선순위큐사례
시물레이션시스템 네트워크트래픽 제어 운영체에서의 작업스케쥴링
http://sopt.org
…
Prev. SFP
Return Address
Parameters +
Local Variables
Heap개요
삭제 연산시 항상루트 노드요소를 삭제하여반환
여러 개의값 중에서가장 큰값 (혹은가장작은 값) 을 빠르게찾기 위해설계된 자료구조
히프 정렬은요소의 개수만큼삭제 연산을수행하여 내림차순 / 오름차순으로 정렬수행
Study - Data Structures
최대 히프에서는항상 가장큰 요소가루트 노드가됨
Study - Data Structures
수행과정
10
69
22
30
318162
22
69
2
31
3081610
- 69 10 30 2 16 8 31 22
Heap
Study - Data Structures
수행과정
10
22
30
318162
22
31
30
281610
- 69
Heap
Study - Data Structures
수행과정
22 30
281610
22
30
8
21610
- 31 69
Heap
Study - Data Structures
수행과정
22 8
21610
16
22
8
210
- 30 31 69
Heap
Study - Data Structures
수행과정
16 8
210
10
16
8
2
- 22 30 31 69
Heap
Study - Data Structures
수행과정
10 8
2
2
10
8
- 16 22 30 31 69
Heap
Study - Data Structures
수행과정
2 8 2
8
- 10 16 22 30 31 69
Heap
Study - Data Structures
수행과정
2
2
- 8 10 16 22 30 31 69
Heap
Study - Data Structures
수행과정
- 2 8 10 16 22 30 31 69
Heap
Study - Data Structures
수행과정
- 2 8 10 16 22 30 31 69
Heap
공백히프가되었으므로정렬종료
Study - Data Structures
코드분석
Heap
public class Heap {
private Node[] node;private int MAXSIZE = 50;private int length;
public Heap() {
node = new Node[MAXSIZE];length= 0;
}
public Node getNode(int i) { return node[i]; }public int getLength() { return length; }public boolean isEmpty() { return length == 0; }public boolean isFull() { return MAXSIZE == length; }
…}
Node 타입의배열 선언
MAXSIZE 크기의 배열생성및 length 초기화
객체의속성을 받아오는메소드
배열의크기를 알수 있는메소드
Study - Data Structures
코드분석 - 삽입
Heap
…
public void insert(Node node) {
if (isFull()) {
System.out.println("Heap is full");return;
}
int i = ++length;
while (i != 1 && node.getData().compareTo(this.node[i / 2].getData()) > 0) {
this.node[i] = this.node[i / 2];i = i / 2;
}
this.node[i] = node;}
…
노드의삽입이 가능한지판별
i 에 1증가한 length를 넣음
삽입할 node와 해당부모노드의 크기비교-> 삽입할 node보다 작으면 자식노드로이동
해당되는 i 인덱스에 node 삽입
Study - Data Structures
코드분석 - 삭제
Heap
public Node delete() {
Node item = node[1];node[1] = node[length--];
int i = 2, largest;
while (i <= length) {
if (i < length &&node[i].getData().compareTo(node[i + 1].getData()) < 0)
largest = i + 1;
else largest = i;
if (node[largest /2].getData()..compareTo(node[largest].getData()) > 0)break;
Node tmp = node[largest / 2];node[largest / 2] = node[largest];node[largest] = tmp;
i = largest * 2;}
return item;}
}
우선순위가가장 높은원소 삭제
삭제할원소는 item에저장
노드가내려가면서 원소재배열
우선순위가가장 낮은단말 노드를삭제된노드와 변경
Heap성능분석
Study - Data Structures
메모리사용공간
O (n) : n 개의원소에대하여 n 개 + 힙을구현하기위한 n 개의메모리
연산시간
평균시간복잡도
O (n log n)
n 개의요소에대해완전이진트리의레벨은 log (n + 1) 이므로,힙구성시간은 O (log n) 을따른다
따라서, 힙을구성하고다시순서대로뽑아정렬하는시간은 O (n log n) 이다