: 마지막번째 Index부터 차레대로 I번째 인덱스까지 Scanning 하면서 최솟값을 찾는다. 찾은 최솟값을 i (0 <= i <= MAX_INDEX)번째 Index에 위치하도록 Swap한다.
template<class ItemType>
int MinIndex(ItemType values[], int start, int end)
{
int indexOfMin=start;
// scanning ; O(N)
for(int index=start+1; index<=end; index++)
{
if (values[index] < values[indexOfMin] )
indexOfMin=index;
}
return indexOfMin;
}
template<class ItemType>
void SelectionSort(ItemType values[], int numValues)
{
int endIndex=numValues-1;
// Minindex() 에서 for 중첩 : O(N^2)
for(int current=0; current<endIndex; current++)
// current:고정시킬 위치. endIndex는 알아서 자기자리에 와있으므로 등호포함X
{
Swap(values[current], values[Minindex(values, current, endIndex)]);
}
}
: 맨 아래서부터 위로 올라가면서 두 pair씩 비교하고, 비교할 때마다 작은 값이 위로 가도록 Swap해준다. 전체 Scan 1회마다 1개씩 정렬된다는 보장이 있다.
template<class ItemType>
void BubbleSort(ItemType values[], int numValues)
{
int current=0;
// BubbleUp에서도 for문을 돌기때문에 While까지 해서 반복문 중첩. O(N^2)이 된다.
while(current<numValues-1) // numValues-1 : endIndex. 처음부터 마지막 전까지.
// 마지막 인덱스는 정렬하지 않아도 마지막 전까지 정렬하면 알아서 자기 자리 찾으므로 등호 포함하지 않는다.
{
// current : 하나씩 증가한다. , numValues-1 : endIndex는 고정된다.
BubbleUp(values, current, numValues-1);
current++;
}
}
template<class ItemType>
void BubbleUp(ItemType values[], int startIndex, int endIndex)
{
// endIndex부터 위치 찾을 인덱스(startIndex) 전까지 반복문 실행한다.
for(int index=endIndex; index>startIndex; index--)
{
if(values[index] < values[index-1]) // 자신의 바로 앞과 비교한다.
Swap(values[index], values[index-1]);
}
}
template<class ItemType>
void InsertItem(ItemType values[], int start, int end)
{
bool finished=false;
int current=end; // initial state : 고정할 위치 에서 시작
bool moreToSearch=(current!=start); // 고정할 위치에서 처음까지 다 돌면 끝
// while : O(N)
while(moreToSearch && !finished)
{
if(values[current]<values[current-1]) // 자신의 앞 칸과 비교
{
Swap(values[current], values[current-1]);
current--; // 앞으로 간다
moreToSearch=(current!=start);
}
else
finished=true; // 내 자리 찾으면 끝나고 나온다
}
template<class ItemType>
void InsertionSort(Itemtype values[], int numValues)
{
// for문 : InsertItem에서도 while문 돌기 때문에 반복문 중첩으로 O(N^2)이 된다.
for(int count=0; count<numValues; count++) // count는 고정할 위치
InsertItem(values, 0, count);
}
template<class ItemType>
void HeapSort(ItemType values[], int numValues)
{
int index;
// Array를 heap으로 만들어준다. 이때도 nlogN time complexity가 발생한다.
// Non terminal node에 대해서 ReheapDown을 해서 array를 heap으로 만드는 방법
// Terminal node에 대해서 ReheapUp을 해서 array를 heap으로 만드는 방법도 가능하다.
// 똑같이 Time complexity는 nlogN이 된다.
for(index=numValues/2-1; index>=0; index--)
// leaf노드 시작 지점 전까지, root까지, 아래서 위로
ReheapDown(values, index, numValues-1);
// array를 정렬한다. 이때도 nlogN time complexirt가 발생한다.
for(index=numValues-1; index>=1; index++)
//가장 뒤부터 자리잡는다, 0은 알아서 정렬되므로 1까지만, 젤 뒤에서 앞으로 한 칸씩
{
Swap(values[0], values[index]);
// root(가장큰값), 고정시킬위치
ReheapDwon(values,0,index-1);
// 0부터 index-1까지 내려가게 하는 Reheapdwon
}
}
// Recall ) ReHeapDown
template<class ItemType>
void ReHeapDown(ItemType values[], int root, int bottom)
{
int maxChild;
int rightChild;
int leftChild;
leftChild=root*2+1;
rightChild=root*2+2;
if(leftChild<=bottom)
{
if(leftChild == bottom )
maxChild=leftChild;
else
{
if(values[leftChild] <= values[rightChild])
maxChild=rightChild;
else
maxChild=leftChild;
}
if(values[root] < values[maxChild])
{
Swap (values[root], values[maxChild]);
ReHeapDown(maxChild, bottom);
}
}
: Quick Sort는 우선 SplitPoint를 기준으로 SplitPoint의 인덱스 값보다 앞에는 작은 값들, 뒤에는 큰 값이 오도록 하는 과정을 반복하며 정렬하는 것이다. Divide and Conquer 원칙을 따른다.
template<class ItemType>
void QuickSort(ItemType values[], int first, int last)
// 어디서부터 어디까지
{
if(first<last) // general case
{
int splitPoint;
// 어떻게 자리를 찾는지 과정이 중요하다.
Split(values, first, last, splitPoint);
// values[splitPoint]보다 작은 값들 모아두게 divide하고 Recursive call
QuickSort(values, first, splitPoint-1);
// vluaes[splitPoint]보다 큰 값들 모아두게 divide하고 Recursive call
QuickSort(values, splitPoint+1, last);
}
// base case : first >= last인 경우
}
template<class ItemType>
void MergeSort(ItemType values[], int fisrt, 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);