🐱🐉🐱🐉导航
前言
- 本篇博客主要介绍选择排序算法中的直接选择排序(SelectSort)和堆排序(HeapSort)
- 代码实现:C语言
直接选择排序
✨基本思想:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完 。
🍊实际上,我们可以每一趟选出两个值,一个最大值一个最小值,然后将其放在序列开头和末尾,这样可以使选择排序的效率得到提高。
ps:选择排序的思路,我们可以在学校上第一次体育课时的场景,老师总是在一排中先挑出最高的同学排到队列右边,以此挑出次高的排到右二……
🎆🎆实现步骤:
前提:给定一组有N个元素的待排序列,要求排升序
- 定义两个下标begin和end,标记每次待排序列的起始位置和结束位置;定义两个下标mini和maxi,均赋初值begin,标记最小树和最大数的下标
- 在元素集合array[begin]--array[end]中选择关键码最小和最大的数据元素,并标记他们的下标分别为mini和maxi
- 若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换
- 更新begin和end,重复上述步骤,直到集合剩余1个元素(begin > end 时结束)
借用网上的gif演示操作:这里只是每次选最小的
🎉🎉🎉代码如下:
void Swap(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } void SelectSort(int* a, int n) { assert(n); int begin = 0; int end = n - 1; while (begin < end) { int mini = begin; int maxi = begin; for (int i = begin + 1; i <= end; i++) { if (a[i] < a[mini]) mini = i; if (a[i] > a[maxi]) maxi = i; } Swap(&a[begin], &a[mini]); //如果begin和maxi重叠,则说明max的值已经备换到了mini,此时要更新一下maxi if (begin == maxi) { maxi = mini; } Swap(&a[end], &a[maxi]); begin++; end--; } }
🔔🔔🔔🔔特性总结:
- 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用,比直接插入排序还拉😅
- 时间复杂度:O(N^2),最好情况也还是O(N^2)
- 空间复杂度:O(1)
- 稳定性:不稳定
堆排序
✨基本思想:
堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。它是通过堆来进行选择数据。需要注意的是排升序要建大堆,排降序建小堆。
🍊关于堆的更详细的知识,这里不再过多赘述,感兴趣的读者请前往我的另一篇博客查看:➡传送门
🎆🎆实现步骤:
前提:给定一组有N个元素的待排序列,要求排升序
- 建堆:排升序,建大堆;排降序,建小堆。建堆过程利用堆的向下调整。
- 选数:利用堆删除的思想进行排序,每次选出堆顶元素,插到序列前面。这里也是利用堆的向下调整
这里展示一张流程图供读者自行走一遍思路:
🎉🎉🎉代码如下:
void Swap(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } void AdjustDwon(int* a, int size, int parent) { int child = parent * 2 + 1; while (child < size) { // 选出左右孩子中小/大的那个 if (child + 1 < size && a[child + 1] > a[child])//大于 建大堆 小于 建小堆 { ++child; } // 孩子跟父亲比较 if (a[child] > a[parent])//大于 建大堆 小于 建小堆 { Swap(&a[child], &a[parent]); parent = child; child = parent * 2 + 1; } else { break; } } } // 降序 -- 建小堆 // 升序 -- 建大堆 void HeapSort(int* a, int n) { assert(n); // 建堆方式2:O(N) for (int i = (n - 1 - 1) / 2; i >= 0; --i) { AdjustDwon(a, n, i); } // O(N*logN) int end = n - 1; while (end > 0) { Swap(&a[0], &a[end]); AdjustDwon(a, end, 0); --end; } }
🔔🔔🔔🔔特性总结:
- 堆排序使用堆来选数,效率就高了很多。
- 时间复杂度:O(N*logN)
- 空间复杂度:O(1)
- 稳定性:不稳定
学习记录:
- 本篇博客整理于2022.7.9
- 请多多指教🌹🌹
- 如果觉得写的不错,看完了别忘了点赞啊,感谢支持😏😏