原理
选择排序,是将一个数组遍历后选出最小值与未排序的第一位数组交换位置,直至数组为升序数组(也可以排降序)。
下面我们看一下动画演示
代码实现
Dev C++版本
该代码main函数的写法仅限Dev C++ !!!!
#include <iostream>
using namespace std;
void test01(int a[], int len)
{
//int a[len];
for (int i = 0; i < len - 1; i++) {
int min = i; /*这里不可以写成min=a[0] ,不然循环每一次都是初始化为
第一位元素。最终只排了一次有效序,且第一位为最小值 */
int j = i + 1;
for (; j < len; j++) /*最初想看一下是不是j越界了,把len变为len-1,想错了,
这样j还是会越界 */
if (a[min] > a[j])
{
min = j;
}
// int t = a[i];
// a[i] = a[min];
// a[j] = t;
int t = a[i];
a[i] = a[min];
a[min] = t; //将a[i]和a[j]交换位置
/*为什么这里的交换不能写成 a[j] = t;??? 因为j经过最后一次for循环判断后变为len,
数组越界了,所以得用min,最后的最大值为len-1 */
}
}
int main()
{
int len;
cout << "请输入数组长度:";
cin>>len;
int a[len];
//int a[5] = { 5,2,9,1,6 };
cout<<"请输入数组:";
for(int k=0;k<len;k++){
cin>>a[k];
}
test01(a, len);
cout << "排序后数组为:";
for (int j = 0; j < len; j++)
cout << a[j] << " ";
cout << endl;
return 0;
}
代码在Dev C++的编辑器上可运行,不过在visual studio上不可以,报错原因是数组下标的表达式要用常量,不能是变量,因为我是比较喜欢在控制台里自定义然后输入输出的,希望广大C友来帮忙解决一下这个问题
以下是在visual studio下运行版本
int main()
{
//int len;
//cout << "请输入数组长度:";
//cin >> len;
const int len = 5;
int a[len];
//int *a = (int*)malloc(len);
//int a[5] = { 5,2,9,1,6 };
cout << "请输入数组:";
for (int k = 0; k < len; k++) {
cin >> a[k];
}
test01(a, len);
cout << "排序后数组为:";
for (int j = 0; j < len; j++)
cout << a[j] << " ";
cout << endl;
return 0;
}
注意事项
for (int i = 0; i < len - 1; i++) {
int min = i;
int j = i + 1;
for (; j < len; j++){
if (a[min] > a[j])
{
min = j;
}
}
int t = a[i];
a[i] = a[min];
a[min] = t;
}
排序步骤:
- 先封装排序算法,写一个for循环,这里循环判断条件做了优化:len-1,因为排序到最后一位元素时不用排序了,第一个for是为了找未排序的元素。
- 第二个for是为了给未排序元素进行排序,若a[j]<a[min],则交换两个的数组下标。
- 在嵌套for外,交换值。
注意: 这里的值交换不能写成a[j]=t,因为for循环后j=len,如果用j做数组下标,此时j已经越界了,因为我们知道最大下标数等于len-1
小结
选择排序到这也就全部写完啦,最后我们再做一下复杂度分析
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
下期写归并排序,到时见😜!