【排序演算法】選擇排序(C++實現)
阿新 • • 發佈:2019-01-26
選擇排序演算法就是每一趟從待排序的記錄中選出關鍵字最小(最大)的記錄,順序放在已排好序的子檔案的最後(最前),直到全部記錄排序完畢。常見的選擇排序有直接選擇排序(Selection Sort),堆排序(Heap Sort),平滑排序(Smooth Sort),笛卡爾樹排序(Cartesian Sort),錦標賽排序(Tournament Sort),迴圈排序(Cycle)。下面介紹前兩種:
(一)直接選擇排序
最差時間複雜度:O(n^2)
最優時間複雜度:O(n^2)
平均時間複雜度:O(n^2)
穩定性:不穩定
直接選擇排序(Selection Sort),這是一種簡單直觀的排序演算法。它首先在未排序序列中找到最小(大)元素,存放到排序序列的其起始位置,然後再從剩餘未排序的序列元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到所有元素排序完畢。
演算法示意圖:
實現程式碼:
void SelectSort(int *a, int len)
{
for (int i=0; i<len-1; i++)
{
int k = i;
int key = a[i];
for (int j=i+1; j<len; j++)
{
if (a[j]<key)
{
k = j;
key = a[j];
}
}
if (k!=i)
swap(a[i], a[k]);
}
}
(二)堆排序
最差時間複雜度:O(nlogn)最優時間複雜度:O(nlogn)
平均時間複雜度:O(nlogn)
穩定性:不穩定
堆排序(Heap Sort)
其左子節點的下標為 (2*i+1);
其右子節點的下標為 (2*i+2);
其父節點的下標為 floor((i-1)/2)。
在堆的資料結構中,堆中的最大值總是位於根節點。堆中定義一下三個操作:
1.最大堆調整(Max Heapify):在假定節點i的左右子節點為根的兩顆二叉樹都是最大堆的前提下,確保父節點大於子節點,否則下降原父節點,最終使以i為根的子樹成為最大堆。
2.建立最大堆(Build Max Heap):將堆所有資料重新排序,對所有非葉子節點呼叫一次Max Heapify。
3.堆排序(Heap Sort):首先建立最大堆,然後依次將堆的根節點與末節點交換、剔除末節點、對根節點進行最大堆調整,直到堆中的節點數為1,排序結束。
演算法示意圖:
實現程式碼:
// 最大堆調整
void MaxHeapify(int *a, int i, int heapSize)
{
int l = (i+1)*2-1;
int r = (i+1)*2;
int largest;
if (l<=heapSize && a[l]>a[i])
largest = l;
else
largest = i;
if (r<=heapSize && a[r]>a[largest])
largest = r;
if (largest!=i)
{
swap(a[i], a[largest]);
MaxHeapify(a, largest, heapSize);
}
}
// 建立最大堆
void BuildMaxHeap(int *a, int len)
{
for (int i=len/2-1; i>=0; i--)
{
MaxHeapify(a, i, len-1);
}
}
// 堆排序
void HeapSort(int *a, int len)
{
BuildMaxHeap(a, len);
for (int i=len-1; i>0; i--)
{
swap(a[0], a[i]);
MaxHeapify(a, 0, i-1);
}
}