选择排序
思想:
如果有N个元素需要排序,那么首先从N个元素中找到最小的那个元素与第0位置上的元素交换,然后再从剩下的N-1个元素中找到最小的元素与第1位置上的元素交换,之后再从剩下的N-2个元素中找到最小的元素与第2位置上的元素交换,.......直到所有元素都排序好。
优化:选择排序平均时间复杂度O(N^2),还可以进行优化,可以在一次[数组遍历](https://so.csdn.net/so/search?q=数组遍历&spm=1001.2101.3001.7020)中同时找到最大值和最小值,这样就减少了数组的循环次数,效率提高。
代码
示例(未优化):
// 未优化
// 采用两层循环实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort1(int arr[], int len)
{
for(int ii=0;ii<len-1;ii++)
{
int posmin = ii; // 每趟循环选出的最小值的位置(数组的下标)。
for(int jj=ii+1;jj<len;jj++) // 每趟只需要比较ii+1......len-1之间的元素,ii之前的元素是已经排序好的。
{
// 找出值更小的元素,记下它的位置。
if(arr[posmin]>arr[jj]) posmin = jj;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (posmin != ii) swap(arr[ii],arr[posmin]);
}
}
// 采用递归实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort2(int arr[], int len)
{
if(len==0) return;
int posmin = 0; // 每趟循环选出的最小值的位置(数组的下标)。
for(int ii=0;ii<len;ii++)
{
// 找出值更小的元素,记下它的位置。
if(arr[posmin]>arr[ii]) posmin = ii;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (posmin != 0) swap(arr[0],arr[posmin]);
selectsort2(arr+1,--len); // 递归调用自身
}
示例(优化后):
// 未优化
// 采用两层循环实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort1(int arr[], int len)
{
for(int ii=0;ii<len-1;ii++)
{
int posmin = ii; // 每趟循环选出的最小值的位置(数组的下标)。
for(int jj=ii+1;jj<len;jj++) // 每趟只需要比较ii+1......len-1之间的元素,ii之前的元素是已经排序好的。
{
// 找出值更小的元素,记下它的位置。
if(arr[posmin]>arr[jj]) posmin = jj;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (posmin != ii) swap(arr[ii],arr[posmin]);
}
}
// 采用递归实现的方法。
// 参数arr是待排序数组的首地址,len是数组元素的个数。
void selectsort2(int arr[], int len)
{
if(len==0) return;
int posmin = 0; // 每趟循环选出的最小值的位置(数组的下标)。
for(int ii=0;ii<len;ii++)
{
// 找出值更小的元素,记下它的位置。
if(arr[posmin]>arr[ii]) posmin = ii;
}
// 如果本趟循环的最小的元素不是起始位置的元素,则交换它们的位置。
if (posmin != 0) swap(arr[0],arr[posmin]);
selectsort2(arr+1,--len); // 递归调用自身
}
算法分析
时间复杂度:
- 最好:O(n^2)
- 最坏:O(n^2)
- 平均:O(n^2)
空间复杂度:O(1)
稳定性:稳定