- toc {:toc}
Sorting
- 정렬 : 선택, 버블, 삽입, 이진, 퀵, 합병
Selection Sort
-
각 pass 마다, 가장 작은 값을 찾고 맨 앞으로 전송한다.
-
Linear Search로 순회하면서 가장 작은 값을 찾고 앞으로 보낸다.
-
시간 복잡도 = (n-1) + (n-2) + … + 2 + 1 = O(N^2)
template <class ItemType>
void SelectionSort (ItemType values[ ], int numValues ){
int endIndex = numValues - 1 ;
for (int current = 0 ; current < endIndex; current++)
Swap (values[current],
values[MinIndex(values, current, endIndex)]);
}
template <class ItemType>
int MinIndex(ItemType values[ ], int start, int end){
int indexOfMin = start ;
for(int index = start + 1 ; index <= end ; index++)
if (values[ index] < values [indexOfMin])
indexOfMin = index ;
return indexOfMin; // 최소값을 갖는 인덱스를 반환
}
Bubble Sort
- 각 pass 마다, 끝에서부터 앞으로 순차적으로 비교하면서 전송한다.
- 시간 복잡도 : (n-1) + (n-2) + … + 2 + 1 = O(N^2) (항상 그런 것은 아니다.)
template<class ItemType>
void BubbleSort(ItemType values[], int numValues){
int current = 0;
while (current < numValues - 1){
BubbleUp(values, current, numValues-1);
current++;
}
}
template<class ItemType>
void BubbleUp(ItemType values[], int startIndex, int endIndex){
for (int index = endIndex; index > startIndex; index--)
if (values[index] < values[index-1])
Swap(values[index], values[index-1]);
}
Insertion Sort
- 각 pass 마다, 키값을 하나 선택하고 키값이 올바른 위치로 이동하도록 만든다.
- 시간 복잡도 : O(N^2)
template <class ItemType>
void InsertionSort (ItemType values[ ], int numValues )
{
for (int count = 0 ; count < numValues; count++)
InsertItem (values , 0 , count);
}
template <class ItemType>
void InsertItem (ItemType values[ ], int start, int end){
bool finished = false;
int current = end;
bool moreToSearch = (current != start);
while (moreToSearch && !finished){
if (values[current] < values[current - 1]){
Swap(values[current], values[current - 1);
current--;
moreToSearch = ( current != start );
}
else
finished = true ;
}
}
Heap Sort
- 힙 정렬
- 정렬되지 않은 트리를 힙 속성이 만족하도록 정렬한다.
- 루트를 빼고 힙 속성을 만족하도록 정렬하는 과정을 반복한다.
- 시간 복잡도 : (N/2) x O(logN) + (N-1) x O(logN) = O(NlogN)
template <class ItemType>
void HeapSort (ItemType values[ ], int numValues ){
int index ;
for (index = numValues/2 - 1; index >= 0; index--)
ReheapDown ( values , index , numValues - 1 ) ;
// Sort the array.
for (index = numValues - 1; index >= 1; index--){
Swap (values [0] , values[index]);
ReheapDown (values , 0 , index - 1);
}
}
Quick Sort
- 기준을 설정하고 기준과 비교해 작은 것, 큰 것을 분류한다.
- 왼쪽에서, 오른쪽에서 기준을 설정하고 분류하는 작업을 계속한다.
- 시간 복잡도
- 기준을 계속해서 중간 값을 갖는 경우 : O(NlogN)
- 기준이 한쪽 끝으로 몰릴 경우, 최악 : O(N^2)
template <class ItemType>
void QuickSort (ItemType values[ ], int first, int last )
ascending order
{
if (first < last){
int splitPoint ;
Split (values, first, last, splitPoint);
QuickSort(values, first, splitPoint - 1);
QuickSort(values, splitPoint + 1, last);
}
}
Merge Sort
- 합병 정렬 : 계속 분할한 후 합칠 때 비교하여 정렬한다.
- 시간 복잡도 : O(NlogN)
template <class ItemType>
void MergeSort (ItemType values[ ], int first, int last )
{
if (first < last){
int middle = ( first + last ) / 2;
MergeSort(values, first, middle);
MergeSort(values, middle + 1, last);
Merge(values, first, middle, middle + 1, last);
}
}
Testing
- 정렬이 잘 작동하는지를 확인하기 위해서는 다음의 배열을 생성해 테스트해본다.
- 역순의 배열
- 거의 정렬된 배열
- 동일 원소를 가진 배열