如何将一个随机数组如[10,5,2,9,19,15,14]排序(从小到大)?对于初学者来说这是一个值得思考的问题。
很多地方都介绍冒泡排序给初学者,个人感觉选择排序更容易理解
1.选择排序:
选择排序( Selection sort)的思想非常直观易懂,我们每一次遍历数组找出数组的最大值,放到末尾,然后找到第二大的值,放在倒数第二位。依次即可排好序
当然也可以选择最小的放第一位,第二小的放第二位。
如数组[10,5,2,9,19,15,14]
1.数组最大值为19,将19与最后一位的数字14交换。结果为: [10,5,2,9,14,15,19]
2.第二大的数组为15,将15与倒数第二位的数字交换。结果为: [10,5,8,9,14,15,19]
3.同理14与14交换,结果为: [10,5,8,9,14,15,19]
4. 10与9交换, [9,5,8,10,14,15,19]
5. 9与8交换, [8,5,9,10,14,15,19]
6.5与8交换 [5,8,9,10,14,15,19]
完成排序
实现代码如下
//选择排序
void SelectionSort(int* arr, int n)
{
//1.数组为空或者数组长度为0,1不需要排序
if (arr == nullptr || n <=1)
return;
//2.排序
//0~n-1选择最大
//0~n-2选择最大
//...
//0~0选择最大
//一共选择了n次,
for (int i = 0; i < n; i++)
{
int maxindex = 0;
for (int j = 0; j < n - i; j++)//将最大的数字放到最后,然后只要从0到n-i位置找即可
{
if (arr[maxindex] < arr[j])
maxindex = j;
}
swap(arr[maxindex], arr[n - 1 - i]);//将最大位置的数与没有排序数字中的最后一个数交换
}
}
c++可以直接使用swap进行交换,如果使用C语言需要自己实现
void Swap(int*a,int*b)
{
int t=*a;
*a=*b;
*b=t;
}
2.选择排序的特点
2.1时间复杂度
外层循环有n次,内层循环由n到1,时间复杂度为1+2+3+4....+n
故时间复杂度为O(N^2)
2.2空间复杂度
用到了一个变量保存最大值的下标,交换用到了一个变量,故时间复杂度为O(1)
2.3稳定性
选择排序是不稳定的,会导致相同元素的先后顺序不一样
3.简单测试
测试代码如下(可以直接运行)
#include<iostream>
using namespace std;
//选择排序
void SelectionSort(int* arr, int n)
{
//1.数组为空或者数组长度为0,1不需要排序
if (arr == nullptr || n <=1)
return;
//2.排序
//0~n-1选择最大
//0~n-2选择最大
//...
//0~0选择最大
//一共选择了n-1次,
for (int i = 0; i < n; i++)
{
int maxindex = 0;
for (int j = 0; j < n - i; j++)
{
if (arr[maxindex] < arr[j])
maxindex = j;
}
swap(arr[maxindex], arr[n - 1 - i]);
}
}
int main()
{
int arr[] = { 9,5,8,10,14,15,19 };
int len = sizeof(arr) / sizeof(arr[0]);//求数组长度
SelectionSort(arr, len);
for (int i = 0; i < len; i++)//打印数组看是否成功排序
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
运行结果