1.算法讲解之-详解选择排序

        如何将一个随机数组如[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;
}

运行结果

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘子真甜~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值