竞赛训练4 排序:Selection Sort
题目来源:《挑战程序设计竞赛》
题目:请编写一个程序,读取数列A,利用选择排序法将其按升序排列并输出。另外,请输出程序运行过程中执行交换操作的次数。
输入:在第一行输入定义数组长度的整数N。在第二行输入N个整数,以空格隔开。
输出:输出总计2行。请在第一行输出排序后的数列。数列相邻元素用一个空格隔开。第二行输出元素交换的次数。
限制:1≤N≤100 0≤A的元素≤100
输入示例
6
5 6 4 2 1 3
输出示例
1 2 3 4 5 6
4
和插入排序、冒泡排序一样,选择排序在各个计算步骤中,数组也分成“已排序部分”和“未排序部分”。思想也很简单,在未排序部分找到最小的元素,然后将该元素和未排序部分的第一个元素交换即可。
先贴我的代码,我是将最小元素值和下标记下来然后比较和交换,这样会显得有些冗长:
#include<iostream>
using namespace std;
#define MAX 1000
int main()
{
int n,a[MAX],i,j,minv,cnt,cj;
cin>>n;
for(i=0;i<n;++i) cin>>a[i];
minv=9999;
cnt=0;
for(i=0;i<n-1;++i)
{
for(j=i;j<n;++j)
{
if(a[j]<minv)
{
minv=a[j];
cj=j;
}
}
if(a[i]!=minv)
{
swap(a[i],a[cj]);
cnt++;
}
minv=9999;
}
for(i=0;i<n;++i) cout<<a[i]<<" ";
cout<<endl<<cnt;
return 0;
}
之前犯了一个很容易犯的问题,暂存最小值的变量minv在比较完一轮后忘了将其重置,导致输出的结果全是1。
现在贴书上的代码,是将最小元素的下标暂存起来,看起来就没那么乱了:
#include<iostream>
using namespace std;
#define MAX 1000
int main()
{
int n,a[MAX],i,j,minj,cnt;
cin>>n;
for(i=0;i<n;++i) cin>>a[i];
cnt=0;
for(i=0;i<n-1;++i)
{
minj=i;
for(j=i;j<n;++j)
{
if(a[j]<a[minj])
{
minj=j;
}
}
swap(a[i],a[minj]);
if(a[i]!=minv) cnt++;
}
for(i=0;i<n;++i) cout<<a[i]<<" ";
cout<<endl<<cnt;
return 0;
}