选择排序—直接选择排序和堆排序

目录

一、直接选择排序

直接选择排序特性总结: 

二、堆排序 


一、直接选择排序

🤔基本思想:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
🎥动态演示:

💡实现思路:

选择排序的实现比较简单,其就是依次遍历数组,找出最小或者最大的元素与最前面或者最后面元素进行交换,然后遍历剩下的数据,再找再换,直到遍历完毕。

⏩排序优化:

对于传统选择排序,我们每次只找最大或者最小的进行排序,这样有点浪费时间,为了提高效率,我们可以每次选出最大的和最小的,最小的放前面,最大的放后面,不断缩小区间,直到完成排序。

存在缺陷:

提高了效率的同时也可能会带来风险,比如我们要对数组arr[5]={9,1,2,5,7}进行排序。

第一次遍历我们得到最大元素为a[0],最小元素为a[1],最小元素要放在最左边,所以a[0]与a[1]进行交换,此时a[0]位置放的是元素1,为最小元素符合排序。但此时最大元素要放在最右边,最大元素为9,我们记录的是a[0]位置,但此时a[0]位置元素已不是9,所以这就导致排序失败,出现这种重叠情况,我们需要修正下max。

✍🏻代码演示:

void Swap(int* pa, int* pb)
{
	int tmp = *pa;
	*pa = *pb;
	*pb = tmp;
}

//直接选择排序
void SelectSort(int* a, int n)
{
	int left = 0;
	int right = n - 1;
	while (left < right)
	{
		int mini = left, maxi = left;
		for (int i = left + 1; i <= right; i++)
		{
			if (a[i] < a[mini])
			{
				mini = i;//遍历数组找出最小值下标
			}
			if (a[i] > a[maxi])
			{
				maxi = i;//遍历数组找出最大值下标
			}
		}
		//升序小值放左,大值放右
		Swap(&a[left], &a[mini]);
		//如果left和maxi重叠,修正maxi
		if (left == maxi)
		{
			maxi = mini;
		}
		Swap(&a[right], &a[maxi]);
		//交换完缩小区间
		left++;
		right--;
	}
}

直接选择排序特性总结: 

📝:直接选择排序的思想非常好理解,但因为其效率不高所以在实际中很少用。

🍒:时间复杂度:O(N^2)

🍒:空间复杂度:O(1)

🍒:稳定性:不稳定

二、堆排序 

关于堆排序的讲解在下面的博文中讲的很清楚:

堆的应用—堆排序和TopK问题_Fan~Fan的博客-CSDN博客_堆排序的应用

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
选择排序算法: 1. 从数组中选择最小的元素,将其放置在数组的起始位置。 2. 在剩余的元素中选择最小的元素,将其放置在已排序元素的末尾。 3. 重复步骤2直到所有元素都已排序。 代码实现: ``` function selectionSort(arr) { for (let i = 0; i < arr.length - 1; i++) { let minIndex = i; for (let j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } if (minIndex !== i) { [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; } } return arr; } ``` 堆排序算法: 1. 构建一个最大堆(或最小堆)。 2. 将堆顶元素与最后一个元素交换,然后将堆的大小减1。 3. 对新的堆顶元素进行堆化,重复步骤2和3直到堆的大小为1。 代码实现: ``` function heapSort(arr) { buildMaxHeap(arr); let heapSize = arr.length; for (let i = arr.length - 1; i > 0; i--) { [arr[0], arr[i]] = [arr[i], arr[0]]; heapSize--; maxHeapify(arr, 0, heapSize); } return arr; } function buildMaxHeap(arr) { const heapSize = arr.length; for (let i = Math.floor(heapSize / 2); i >= 0; i--) { maxHeapify(arr, i, heapSize); } } function maxHeapify(arr, i, heapSize) { const left = 2 * i + 1; const right = 2 * i + 2; let largest = i; if (left < heapSize && arr[left] > arr[largest]) { largest = left; } if (right < heapSize && arr[right] > arr[largest]) { largest = right; } if (largest !== i) { [arr[i], arr[largest]] = [arr[largest], arr[i]]; maxHeapify(arr, largest, heapSize); } } ``` 选择排序算法的时间复杂度为$O(n^2)$,堆排序算法的时间复杂度为$O(n\log n)$。虽然堆排序的时间复杂度比选择排序更优,但是堆排序的常数项较大,因此在实际应用中需要根据具体情况选择合适的排序算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值