1. 우선순위 큐와 선택/삽입 정렬 (Priority Queue and Selection/Insertion Sort)
반응형
원소와 키가 존재하는 큐. 각 항목이 (키, 원소) 쌍으로 구성됨.
우선순위 큐의 주요 함수
void insertItem(e, k); // 키 k인 원소 e를 삽입 elem removeMin(); // k가 가장 낮은 원소 삭제, 반환 int size(); boolean isEmpty(); elem minElement(); // k가 가장 낮은 원소 반환 elem minKey(); // 가장 낮은 k 반환
우선순위 큐를 활용한 정렬
우선순위 큐를 이용하여 리스트를 정렬할 수 있다.
def PQ-sort(L): P = PriorityQueue() while(! L.isEmpty()): e = L.pop() P.insertItem(e) while(! P.isEmpty()): e = P.removeMin() L.append(e) return L
큐의 구현
큐는 순서가 있는 리스트와 순서가 없는 리스트를 활용하여 구현할 수 있다.
무순리스트
void insertItem(e); // O(1) 시간 소요. 리스트의 앞,뒤 중 아무대나 원소 추가 elem minElement(); // O(n) 시간 소요. k가 최소인 값을 찾아야 함
순서리스트
k에 따라 정렬된 리스트로 구현
void insertItem(e); // O(n) 시간, 넣을 위치를 찾아야 하므로 elem minElement(); // O(1) 시간, 이미 정렬되어 있으므로
무순리스트와 순서리스트 비교
우선순위 큐 | insertItem | removeMin | minKey, minElement | 정렬 방식 |
무순리스트 | O(1) | O(n) | O(n) | 선택 정렬 |
순서리스트 | O(n) | O(1) | O(1) | 삽입 정렬 |
큐를 이용한 정렬
선택 정렬Selection Sort
무순리스트로 구현한 우선순위 큐 사용
- n회의 insertItem을 수행하여 원소를 모두 PQ에 넣는데 n 시간 소요
- n회의 removeMin을 수행하여 원소를 모두 PQ에서 꺼내는데 n에 비례한 시간 소요
n+(n−1)+(n−2)+⋯+(1) - 총 O(n2) 시간 소요
삽입 정렬Insertion Sort
순서리스트로 구현한 우선순위 큐 사용
- n회의 insertItem을 수행하여 원소를 모두 PQ에 넣는데 n에 비례한 시간 소요
n+(n−1)+(n−2)+⋯+(1) - n회의 removeMin을 수행하여 원소를 모두 PQ에서 꺼내는데 n 시간 소요
- 총 O(n2) 시간 소요
제자리 정렬In-Place Sort
원래 리스트 공간 (n개) 이외에 상수 크기의 메모리만을 사용하는 제자리 정렬.
정렬이 외부 우선순위 큐를 사용하는 대신, 제자리에서 정렬이 수행되도록 구현
리스트의 앞부분을 정렬 상태로 유지하며, 뒷부분을 무순 우선순위 큐로 보고 선택 정렬 수행 (Swap을 활용)
def inPlaceSelectionSort(A): n = len(A) for i in range(0, n-1): minLoc = i for j in range(i+1, n): if A[j] < A[minLoc]: minLoc = j swap(A[i], A[minLoc]) return A
def inPlaceInsertionSort(A): n = len(A) for i in range(1, n): save = A[i] j = i-1 while j >= 0 and A[j] > save: A[j+1] = A[j] j = j-1 A[j+1] = save return A
선택 정렬 vs 삽입 정렬
- 모두 O(n2) 시간 소요.
- 내부 반복문: O(n) 선형 탐색
- 외부 반복문: O(n) 패스
- 제자리 버전은 O(1) 공간 소요
- 적은 n에 대해 유용
초기 리스트가 거의 혹은 완전히 정렬된 경우 제자리 삽입 정렬이 더 빠르다. (내부 반복문이 O(1) 시간에 소요되어 전체적으로 O(n) 시간이 소요되므로)
swapElements 작업이 비싼 경우에는 선택 정렬이 빠르다. (선택 정렬에서 swap이 O(1) 시간 수행되는데 비해, 삽입 정렬에서는 최악의 경우 O(n)회 소요되므로)
반응형
'학부 수업 > 알고리즘' 카테고리의 다른 글
6. 비교 기반 정렬 알고리즘(Comparison-based Sorting) (0) | 2020.09.29 |
---|---|
5. 퀵 정렬(Quick Sort) (0) | 2020.09.29 |
4. 합병 정렬과 분할 정복법 (Merge Sort, Devide and Conquer) (0) | 2020.09.22 |
3. 힙 정렬 (Heap Sort) (0) | 2020.09.15 |
2. 힙 (Heap) (0) | 2020.09.10 |
댓글
이 글 공유하기
다른 글
-
5. 퀵 정렬(Quick Sort)
5. 퀵 정렬(Quick Sort)
2020.09.29퀵 정렬은 분할 정복법을 이용한 정렬 알고리즘이다. 기준 원소 p(pivot)를 정하여 정렬하고자 하는 리스트를 LT (p보다 작은 원소들), EQ (p와 같은 원소들), GT (p보다 큰 원소들)의 세 부분으로 분할하고, LT와 GT를 재귀를 통해 각각 정렬 후, 세 부분을 합쳐 정렬을 완료한다. def quickSort(L): if len(L)> 1: i = -1 # pivot, 보통은 마지막 원소를 사용 LT, EQ, GT = partition(L, i) quickSort(LT) quickSort(GT) L = merge(LT, EQ, GT) return L 리스트 분할 리스트의 각 원소를 차례대로 꺼내어 기준 원소 p와 비교하여 분할하기 때문에, 분할 단계는 $O(… -
4. 합병 정렬과 분할 정복법 (Merge Sort, Devide and Conquer)
4. 합병 정렬과 분할 정복법 (Merge Sort, Devide and Conquer)
2020.09.22분할 정복법Devide and Conquer 분할 정복법은 대표적인 알고리즘 설계 기법의 일종으로, 큰 문제를 작은 문제 여러 개로 분할하여, 하나씩 해결하는 기법이다. 분할 정복의 예시로 합병 정렬과 퀵 정렬이 있다. 합병 정렬 분할 정복법을 이용한 정렬 알고리즘이다. 힙 정렬과 마찬가지로 비교에 기초한 정렬이며, O(nlogn) 시간에 수행된다. 힙 정렬과는 달리 외부의 우선순위 큐를 이용하는 것이 아니라, 데이터에 순차적으로 접근하여 정렬하므로, 순차 데이터를 정렬하기에 적절하다. def mergeSort(L): if len(L) > 1: L1, L2 = L[:len(L)//2], L[len(L)//2:] # Devide mergeSort(L1) # Conquer mergeSort(L2) L… -
3. 힙 정렬 (Heap Sort)
3. 힙 정렬 (Heap Sort)
2020.09.15insertItem, removeMin 함수가 O(logn)의 시간복잡도를 갖는 힙으로 구현된 우선순위 큐를 사용하면, n개의 원소를 갖는 리스트를 O(nlogn)시간에 정렬할 수 있다. 이는 O(n2) 시간이 걸리는 선택정렬이나 삽입정렬에 비해 훨씬 빠른 속도이다. def heapSort(L): H = Heap() while !L.isEmpty(): k=L.removeFirst() H.insertItem(k) while !H.isEmpty(): k=H.removeMin() L.addLast(k) return L 힙 정렬의 개선 제자리 힙 정렬은 힙 정렬의 공간 복잡도를 줄일 수 있다. 상향식 힙 생성은 힙 정렬의 속도를 높일 수 있다. 제자리 힙 정렬 정렬할 리스트가 배열로 주어… -
2. 힙 (Heap)
2. 힙 (Heap)
2020.09.10힙 힙은 내부노드에 키를 저장하며, 다음 두 가지 속성을 만족하는 이진트리이다. 힙 순서(Heap Order): 루트노드를 제외한 모든 내부노드 v에 대해, key(v)≥key(parent(v)) 완전 이진 트리: 힙의 높이를 h라 하면, i=0,⋯h−1에 대해, 깊이 i인 노드가 2i개 존재 깊이 h−1에서, 내부노드들은 외부노드의 왼쪽에 존재 힙의 마지막 노드는, 깊이 h−1의 가장 오른쪽 내부노드이다. 힙의 높이 n개의 키를 저장하는 힙의 높이는 O(logn)이다. 깊이 i=0,1,2,⋯,h−2에 2i개의 키, 그리고 깊이 h−1에 적어도 한 개의 키가 존재하므로 $n…
댓글을 사용할 수 없습니다.