選擇排序的基本思想:每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,直到全部待排序的數據元素排完 。
第一種實現方法:
void SelectSort(int* arr, int n)
{for (int j = 0;j < n - 1;j++){int mini = n - 1;int begin = j;for (int i = begin;i < n - 1;i++){if (arr[mini] > arr[i])mini = i;}int tmp = arr[mini];arr[mini] = arr[begin];arr[begin] = tmp;}
}int main()
{int a[] = { 8,5,7,8,9,0,9,3};SelectSort(a, sizeof(a) / sizeof(a[0]));for (auto e : a){cout << e << " ";};return 0;
}
第二種方法:
如果要將一數組排為升序,將數組第一個元素的下標用begin記錄,數組的第二個元素用end記錄;遍歷第一遍數組將數組中的最大值的下標用maxi記錄,將數組的最小值的下標用mini記錄;第一遍遍歷數組結束后將此時數組的最大值與下標為end元素的值交換,數組最小值與下標為begin元素的值交換,然后--begin? ++end,如此循環,指導begin<=end時結束。
編譯結果情況1,此時的待排序數組是:8,5,7,8,9,0,9,3 可以看到運行結果顯然不是我們所想要的。
void swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int maxi = end, mini = begin;for (int i = begin;i <= end;i++){if (a[maxi] < a[i])maxi = i;if (a[mini] > a[i])mini = i;}swap(a[begin], a[mini]);swap(a[end], a[maxi]);--end;++begin;}
}int main()
{int a[] = { 8,5,7,8,9,0,9,3};SelectSort(a, sizeof(a) / sizeof(a[0]));for (auto e : a){cout << e << " ";};return 0;
}
?
情況2:但是當待排序數組是 8,5,7,8,0,9,9,3時
這是因為第2種情況中的待排序數組進行第四次循環時,出現了交換兩次的問題,如下:
因此我們需要注意當end-begin=1時的情況,接下來對代碼進行優化:
void SelectSort(int* a, int n)
{int begin = 0;int end = n - 1;while (begin < end){int maxi = end, mini = begin;for (int i = begin;i <= end;i++){if (a[maxi] < a[i])maxi = i;if (a[mini] > a[i])mini = i;}swap(a[begin], a[mini]);if(begin+1!=end)//或者是if(end - begin > 1)swap(a[end], a[maxi]);--end;++begin;}
}
int main()
{int a[] = { 8,5,7,8,0,9,9 ,3 };SelectSort(a, sizeof(a) / sizeof(a[0]));for (auto e : a){cout << e << " ";};return 0;
}
?