2. 목차
- 정렬의 의미
- 정렬이 필요한 이유
- 삽입 정렬
- 머지 정렬
- 힙 정렬
- 우선순위 큐
3. 정렬의 의미
- 데이터를 특정 기준에 따라 순서대로 배치
예를들면…. 오름차순(작은 값부터 큰 값으로), 내림차순(큰 값부터 작은 값으로)
1 4 3
1 3 4
4 3 1
오름차순
내림차순
4. 코테 에서 정렬은 언제 필요한가?
- 정렬된 상태에서 동작하는 알고리즘을 사용해야 하는 경우
=> 이진 탐색
=> 병합정렬의 병합
1 4 5 7 9 12 14
9 12 14
9
1
3
5
2
4
6
1 2 3 4 5 6
병합정렬의 병합
이진탐색
5. 대표적인 정렬 알고리즘(삽입정렬)
- 왼쪽은 정렬된 영역, 오른쪽은 비 정렬된 영역으로 나눠짐
- 정렬된 영역이 점점 확장되어 비 정렬된 영역이 없어지는 정렬 방법
- 비 정렬된 영역의 맨 앞의 원소를 정렬된 영역의 적절한 곳에 추가
비정렬
정렬
비정렬
정렬
정렬
삽입정렬 흐름
정렬 비정렬
맨 앞의 원소를 정렬 영역의 정렬 상태를
유지할수 있는 위치에 삽입
삽입정렬 규칙
6. 삽입정렬 과정
1 5 2 3
1 5 2 3
현재 키 : 5
1 < 5 이므로 5는 현재 위치에 넣으면 됨
(결국 제자리)
1 5 3
현재 키 : 2
5 > 2 이므로, 5를 오른쪽으로 이동
1 5 3
현재 키 : 2
1 < 2 이므로 빈칸에 2 삽입
1 2 5
현재 키 :3
5 > 3 이므로 5를 오른쪽 이동
1 2 5
현재 키 :3
2 < 3 이므로 빈칸에 3 삽입
1 3 5
2 정렬 끝
12. 대표적인 정렬 알고리즘(힙 정렬, 힙 이란)
부모노드가 자식노드보다 항상 크면 최대힙, 항상 작으면 최소힙
13. 대표적인 정렬 알고리즘(힙 구축하기)
max_heapify() 연산을 노드번호 N/2 부터 1 까지 차례대로 시행
max_heapify() 연산
1. 현재 노드와 자식 노드 비교(자식 노드가 없다면 연산 종료)
2. 현재 노드가 가장 크지(작지) 않다면, 가장 큰(작은) 자식 노드의 값과 swap
3. 맞바꾼 자식 노드 위치를 현재노드로 해서 1부터 반복
14. 대표적인 정렬 알고리즘(힙정렬, max_heapify)
4번노드가 가장 큰 값, 부모노
드와 swap
Max_heapify(4) 수행
maxheapify(2) 수행
heapify(9/2) -> heapify(1) 까지 차례대로 수행 하면 비정렬 데이터가 힙 구조로 완성됨(정렬된 상태)
=> N/2 부터 하는 이유는… N/2보다 큰 노드는 자식이 없으므로(부모인덱스 는 자식인덱스 *2 혹은 *2 +1)
8
7
15. 대표적인 정렬 알고리즘(힙정렬)
1. 정렬되지 않은 데이터로 최대(소)힙 구축
2. 현재 최대(소)힙의 루트노드와 마지막 노드를 맞바꿈
3. 최대(소)힙 사이즈가 1이면 종료,
최대(소)힙 사이즈를 1 줄임, max_heapify(1) 수행.. 다시 2.로감
17. 우선순위큐의 구현시 고려할 점
원소가 계속 들어오는 상황에서 정렬 상태를 유지 해야함
=> 기존 대부분 정렬 방법은 O(NlogN)
=> 힙정렬을 사용할 경우 삽입/삭제시 O(logN) 보장 => 우선순위큐는 힙을 사용
코테에서 우선순위큐는 최단경로 알고리즘(다익스트라,밸만포드) 구현시 많이 사
용 됨
18. STL에서 제공하는 우선순위큐
- 이미 STL에서 우선순위 큐를 제공함
- 기본적으로 최대힙으로 동작함
10 30 20 5
10
30
10
20
30
10
20
30
10
5
10, 30, 20, 5 순서대로
푸시 하는 경우
30, 20, 10, 5 순서대로
팝 됨(최대 힙)
19. STL에서 제공하는 우선순위큐(실제 사용)
- 우선순위를 따로 제공할수도 있음(사용자 정의타입은 필수)
- 기본적으로 최대힙으로 동작함(큰 값이 먼저)