选择排序的基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
第一种实现方法:
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;
}