选择排序是对冒泡排序算法的改进,在参加排序的所有数组元素中找出最小数据的元素,使它与第一个元素中的数据相互交换位置。然后再在余下的元素中找出最小数据的元素,与第二个元素中的数据相互交换位置,以此类推,直到所有元素成为一个有序的序列。此方法中交换的次数比冒泡排序少,具有较高的效率。
简单的选择排序(Simple Selection Sort)就是通过n-i此关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i个记录交换之。
2.实现步骤:
第一遍加工:第一个元素a(1) 最小数据a(k) 交换位置
第二遍加工:第二个元素a(2) 最小数据a(k) 交换位置
...................
3.举例:
以下面5个无序的数据为例:
56 12 80 91 20(文中仅细化了第一趟的选择过程)
第1趟:12 56 80 91 20
第2趟:12 20 80 91 56
第3趟:12 20 56 91 80
第4趟:12 20 56 80 91
4.C++代码实现
<span style="font-size:18px;">#include<iostream>
using namespace std;
int a[100];
//交换函数,目的是交换数组中两个元素的位置
void swap(int a[],int i,int j)
{
int temp;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
/*在参加排序的所有数组元素中找出最小数据的元素,使它与第一个元素中的数据相互交换位置。
然后再在余下的元素中找出最小数据的元素,与第二个元素中的数据相互交换位置,
以此类推,直到所有元素成为一个有序的序列 */
void Selection_Sort(int a[],int n)
{
for(int i=0;i<n;i++)
{
int flag=-1;//作为标记
int min=a[i];
for(int j=i+1;j<n;j++)
{
if(a[j]<min)
{
min=a[j];//找出最小的元素
flag=j;//标记最小元素的位置
}
}
if(flag!=-1)//防止将原本有序的数组排乱
swap(a,i,flag); //第x小的数与第 x个位置交换
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
}
}
//主程序
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
cin>>a[i];
Selection_Sort(a,n);
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
/*
input
5
5 4 3 2 1
output
1 2 3 4 5
过程:
原始数据: 5 4 3 2 1
第一趟: 1 4 3 2 5
第二趟: 1 2 3 4 5
第三趟: 1 2 3 4 5
第四趟: 1 2 3 4 5
*/ </span>
5.算法分析
从简单的选择排序过程来看,它最大的特点就是交换移动数据次数相对少,这样也就节约了相应的时间。分析它的时间复杂度发现,无论最好最差的情况,其比较次数都是一样多,第i躺排序需要进行n-i次关键字的比较,此时总的需要比较n-1+n-2+......+1=n*(n-1)/2。 而对于交换次数而言,当最好的时候,交换为0次,最差的时候,也就是初始降序时,交换次数为n-1次,基于最终的排序时间是比较次数与交换次数的总和,因此,总的时间复杂度依然是O(n^2)。
尽管与冒泡排序的时间复杂度一样都是O(n^2),但简单的选择排序的性能上还是略优于冒泡排序。
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
简单选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | 稳定 |