Data Structure--排序--插入排序----希尔排序--选择排序--堆排序

灰太狼 2022-10-31 13:51 213阅读 0赞

排序

  • 基本概念及分类
    • 插入排序
    • 希尔排序
    • 选择排序
    • 堆排序

基本概念及分类

排序:排序就是将有记录的东西,按照某个关键字进行递增的或递减的排序下来

稳定性:举例说明,这里有一串数组:1 9 7 4 5 5 6,其中有两个5,在进行排序
在这里插入图片描述
内部排序:元素全部放在内存中的排序。

外部排序:元素太多,内存中放不下,排序过程的要求不能在内外存之间移动数据的排序。
在这里插入图片描述

插入排序

直接将一个数插入到有序的数组中,直接形成新的有序数组,相当于我们玩扑克牌,从小到大整理扑克牌,进行插入.

  1. void insertSort(int* arr, int n){
  2. //假设第一个数据是有序的
  3. //未插入数据[1,n)
  4. for (int i = 0; i < n; ++i){
  5. //从有序的最后一个位置进行遍历
  6. int end = i - 1;
  7. int data = arr[i];
  8. while (end >= 0 && arr[end] >= data){ //满足条件时
  9. //较大的数据向后移动
  10. arr[end + 1] = arr[end]; //数据后移
  11. --end; //循环
  12. }
  13. arr[end + 1] = data; //直接插入
  14. }
  15. }

这个题目,相当于顺序表的头插,大体一致,大家可以具体了解了解 点击此处

希尔排序

在这里插入图片描述

  1. void shellSort(int* arr, int n){
  2. int gap = n; //创建gap值
  3. //一趟哈希排序
  4. while (gap > 1){
  5. gap = gap / 3 + 1; //让其等于一个值进行交换
  6. for (int i = gap; i < n; ++i){ //循环内部
  7. //同组数据,最后一个有序数组的位置
  8. int end = i - gap;
  9. //待插入的数据
  10. int data = arr[i];
  11. while (end >= 0 && arr[end]>data){
  12. arr[end + gap] = arr[end];
  13. end -= gap; //gap逐渐减到1
  14. }
  15. arr[end + gap] = data; //交换
  16. }
  17. }
  18. }

选择排序

插入理解动图点击此处跳转看图
在一组元素中,找到最小的放在最前面,然后剩下的进行二次寻找,直到排序完成!

  1. void selectSort(int* arr, int n){
  2. int start = 0;
  3. int end = n - 1; //定义尾部节点
  4. while (start < end){ //循环开始
  5. //首先找到最小值的位置
  6. int minIdx = start;
  7. int i;
  8. for (i = start + 1; i <= end; ++i){ //进行遍历
  9. if (arr[i] < arr[minIdx]) //如果存在最小的
  10. minIdx=i; //让它等于i
  11. }
  12. //将最小值存在起始位置
  13. Swap(arr, start, minIdx); //这里调用了一个最最最简单的交换元素,我就不具体写了,相信大家也会.
  14. //循环
  15. ++start;
  16. }
  17. }

这一个代码,我们是在每一次遍历寻找的时候,同时找到一个最大的和最小的,这样的话,需要遍历的次数就缩减了一半,提高了我们的效率!

  1. void selectSortPlus(int* arr, int n){
  2. int start = 0;
  3. int end = n - 1;
  4. //我们运用同样的方法,只不过在每次遍历的时候
  5. //寻找一个最大的和一个最小的,这样遍历就能减少一半
  6. while (start < end){
  7. int minIdx = start; //定义最小
  8. int maxIdx = start; //定义最大
  9. for (int j = start + 1; j <= end; ++j){ //开始遍历
  10. if (arr[j] < arr[minIdx]) //找到最小的
  11. minIdx = j; //赋值
  12. if (arr[j]>arr[maxIdx]) //找到最大的
  13. maxIdx = j; //赋值
  14. }
  15. //最小值放在头部
  16. Swap(arr, start, minIdx); //交换
  17. //判断最大值位置是否在起始位置
  18. if (maxIdx == start) //如果最大值在起始位置,就说明只存在一个元素,最大最小相等!
  19. maxIdx = minIdx;
  20. //最大值放在尾部
  21. Swap(arr, end, maxIdx);
  22. ++start; //循环继续
  23. --end;
  24. }
  25. }

堆排序

在这里插入图片描述

  1. void shiftDown(int* arr, int n, int parent){
  2. int child = 2 * parent + 1; //最后一个孩子节点的位置
  3. while (child < n){ //循环
  4. if (child + 1 < n&&arr[child + 1] > arr[child]) //存在则继续
  5. ++child;
  6. if (arr[child]>arr[parent]){ //孩子节点大于父节点,则交换
  7. Swap(arr, child, parent); //交换,如同图中的橙色线
  8. parent = child; //更新
  9. child = 2 * parent + 1; //更新孩子节点
  10. }
  11. else
  12. break; //不满足直接结束
  13. }
  14. }
  15. void heapSort(int* arr, int n){
  16. for (int i = (n - 2) / 2; i >= 0; --i){
  17. shiftDown(arr, n, i); //进行循环调用
  18. }
  19. int end = n - 1; //最后的节点依次减1
  20. while (end > 0){ //end>0继续循环
  21. Swap(arr, end, 0); //交换函数
  22. shiftDown(arr, end, 0); //交换最后一个
  23. --end; //直到end=0,循环结束
  24. }
  25. }

我在上面的图中已经表达的很清楚了,大家具体理解,多看图,就能懂!!!多敲代码!!!一起加油!!!

发表评论

表情:
评论列表 (有 0 条评论,213人围观)

还没有评论,来说两句吧...

相关阅读