• 排序算法3:归并排序与计数排序


    前言

    Hello,小伙伴们,今天我们继续排序算法的学习,大家三连上车不迷路,我们现在开始今天的学习!!!

    1.归并排序

     1.1归并排序的算法思想

    归并排序(MERGE_SORT)是建立在归并的一种游戏哦的排序算法中华给的中庸正科级。

     该算法算是一种采用分治法(Divide and Conquer)的一种典型的用法。将已有的子序列合并,得到完全有序的序列;即先是每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。归并排序核心步骤:

    1.2 代码实现:

     根据上面的思路,我们需要运用二叉树的概念将一个数组分成许多的子数列,之后再进行逐步的合并递归排序。

    我们先来看看代码:

    1. void _MergeSort(int* arr, int left, int right, int* tmp)
    2. {
    3. //归并操作
    4. if (left >= right)
    5. return;
    6. int mid = (left + right) / 2;
    7. //与二叉树递归的思想相近!!
    8. _MergeSort(arr, left, mid, tmp);
    9. _MergeSort(arr, mid + 1, right, tmp);
    10. //合并序列
    11. int begin1 = left, end1 = mid;
    12. int begin2 = mid + 1, end2 = right;
    13. int index = 0;
    14. //升序排序
    15. while (begin1 <= end1 && begin2 <= end2)
    16. {
    17. if (arr[begin1] < arr[begin2])
    18. tmp[index++] = arr[begin1++];
    19. else
    20. {
    21. tmp[index++] = arr[begin2++];
    22. }
    23. for (int i = left; i < right; i++)
    24. {
    25. arr[i] = tmp[i];
    26. }
    27. }
    28. //要么数组1越界,要么数组二越界
    29. while (begin1 <= end1)
    30. {
    31. tmp[index++] = arr[begin1];
    32. }
    33. while (begin2 <= end2)
    34. {
    35. tmp[index++] = arr[begin2];
    36. }
    37. //合并完成
    38. }
    39. void MergeSort(int* arr, int n)
    40. {
    41. //归并操作
    42. int* tmp = (int*)malloc(sizeof(int) * n);
    43. _MergeSort(arr, 0, n - 1, tmp);
    44. free(tmp);
    45. }

     这个运用了二叉树的结构性质,我们在学习了二叉树后就能十分轻松地理解并运用归并排序的思路了。

    接下来,我们来测试一下,我们大代码:

    这样我们的归并排序,就实现完成了。 

    2.计数排序

    2.1计数排序的原理

    计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。操作步骤:

    1. 统计相同元素出现的次数
    2. 根据·统计的结果·将序列会受到原来的序列中。

    2.2代码实现:

     

    1. void CounntSort(int* arr, int n)
    2. {
    3. //找出最大值和最小值
    4. int min =arr[0];
    5. int max = arr[0];
    6. for (int i = 0; i < n; i++)
    7. {
    8. if (arr[i] > max)
    9. {
    10. max = arr[i];
    11. }
    12. if (arr[i] < min)
    13. {
    14. min = arr[i];
    15. }
    16. }
    17. int* tmp = (int*)malloc(sizeof(int) * (max - min + 1));
    18. if (tmp == NULL)
    19. {
    20. perror("malloc Fail!!\n");
    21. exit(1);
    22. }
    23. int range = max - min + 1;
    24. //初始化数组中的元素
    25. memset(tmp, 0, sizeof(int) * (range));
    26. //实现通过下标与时间的映射
    27. for (int i = 0; i < n; i++)
    28. {
    29. tmp[arr[i] - min]++;
    30. }
    31. int index = 0;
    32. for (int i = 0; i < range; i++)
    33. {
    34. //将tmp数组中的数值映射拷贝到数组中
    35. while (tmp[i]--)
    36. {
    37. arr[index++] = i + min;
    38. }
    39. }
    40. }

    计数排序的算法思想相较于其他的排序算法,较为特殊,使用的 场景也很局限,主要是因为他是特殊的非比较排序,在处理整数上能够有过人的表现,但是无法处理浮点数!!

    我们来测试一下我们写的代码:

     

    好,今天的学习就到这里,我们下期再见,拜拜!!! 

  • 相关阅读:
    Android项目在 app 中通过 WebView 访问 url显示空白,使用浏览器可以打开,Android WebView加载出现空白页面问题解决
    【故障诊断分析】FFT轴承故障诊断(包络谱)【含Matlab源码 2002期】
    django ModelForm文件上传(八)
    OpenCV中world模块介绍
    leetcode192.统计词频
    [Spring笔记] Spring-35-AOP通知获取数据
    数据结构与算法3-数组
    uniapp余额银行卡支付密码界面实现(直接复制)
    C++之struct匿名结构体实例(二百四十四)
    LiveData源码分析
  • 原文地址:https://blog.csdn.net/2302_79964175/article/details/141012836