手撕排序之直接选择排序

 前言:

直接选择排序是排序中比较简单的排序,同时也是时间复杂度不是很优的排序。

思想:

本文主要讲解直接选择排序的优化版本。

我们经过一次遍历直接将该数列中最大的和最小的值挑选出来,如果是升序,就将最小的和首元素进行交换,最大的与尾元素进行交换。然后将首部元素++,尾部元素--,重新遍历再次选择次大的和次小的。以此类推。

注意:

按照上面的思路会遇到一些特殊情况,造成排序的失败。

比如说我们先将最大的值赋给尾部元素,如果最大的值正好在头部元素,而最小的值恰好在尾部元素,这样就导致把最大的元素赋给尾部元素时,会把尾部本来的最小值覆盖掉,造成排序的失败。

为了解决这种情况,我们只需要将尾部元素提前存储好就欧克拉~

原码:

void SelectSort(int* a, int n)
{
	int begin = 0;
	int end = n - 1;
	while (begin <= end)
	{
		int maxi = begin, mini = begin;
		for (int i = begin + 1; i < end + 1; i++)
		{
			//找出最大值和最小值的下标
			if (a[i] > a[maxi])
				maxi = i;
			if (a[i] < a[mini])
				mini = i;
		}
		Swap(&a[begin], &a[mini]);
		//max如果被换走,就修正以下
		if (maxi == begin)
			maxi = mini;
		Swap(&a[end], &a[maxi]);
		begin++;
		end--;
	}
}

时间复杂度:
n + n-2 + n - 4 + n - 6……

这也是一个等差数列,所以时间复杂度就是O(N^2)。

显然这并不是一个优的排序算法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

可涵不会debug

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

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

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

打赏作者

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

抵扣说明:

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

余额充值