• 冒泡排序和选择排序


    目录

    一、冒泡排序

    1.冒泡排序的原理

    2.实现冒泡排序

    1.交换函数

    2.单躺排序

    3.冒泡排序实现

    4.测试

    5.升级冒泡排序

    6.升级版代码

    7.升级版测试

    二、选择排序

    1.选择排序的原理

    2.实现选择排序

    1.单躺排序

    2.选择排序实现

    3.测试

    ​4.修改

     5.测试


    一、冒泡排序

    1.冒泡排序的原理

    1.从尾部开始比较相邻的两个元素,如果尾部的元素比前面的大,就交换两个元素的位置。这种方法是排升序的,想排降序的话,一旦尾部的元素比前面的小就交换即可

    比方说,我有一个数组,里面存放的是9 6 3,这三个数字,我的尾部是下标为0的数,也就是9,往下走遇到了6,9比6大,所以交换,数组就会变为6 9 3

    2.往前对每个相邻的元素都做这样的比较和交换,未排序中最大(最小)的那个数就会被排到未排序的数的最后

    2.实现冒泡排序

    1.交换函数

    通过原理的讲解不难看出,冒泡排序要实现多次的交换,因此我们可以写一个简单的交换函数

    1. void Swap(int* x, int* y)
    2. {
    3. int tmp = *x;
    4. //创建中间变量储存x
    5. *x = *y;
    6. *y = tmp;
    7. }

    2.单躺排序

    1. void BobbleSort(int* arr, int n)
    2. //传递数组和数组元素个数
    3. {
    4. int j = 0;
    5. for (j = 0; j < n - 1; j++)
    6. //j
    7. {
    8. if (arr[j] > arr[j + 1])
    9. //不断地进行比较,一遇到大的就进行交换,会将最大的数移动到数组的最后
    10. {
    11. Swap(&arr[j + 1], &arr[j]);
    12. }
    13. }
    14. }

    3.冒泡排序实现

    一趟排好一个数,那么我们一共有n个数,那么循环次数就可以修改成n次

    1. void BobbleSort(int*arr,int n)
    2. //传递数组和数组元素个数
    3. {
    4. int i = 0;
    5. int j = 0;
    6. for (i = 0; i < n; i++)
    7. //n次排序排n个数
    8. {
    9. for (j = 0; j < n - 1; j++)
    10. //j
    11. {
    12. if (arr[j] > arr[j + 1])
    13. //不断地进行比较,一遇到大的就进行交换,会将最大的数移动到数组的最后
    14. {
    15. Swap(&arr[j + 1], &arr[j]);
    16. }
    17. }
    18. }
    19. }

    4.测试

    1. int main()
    2. {
    3. int arr[] = { 9,6,7,5,2,3,4,1,8};
    4. int size = sizeof(arr) / sizeof(arr[0]);
    5. BobbleSort(arr,size);
    6. int i = 0;
    7. for (i = 0; i < size; i++)
    8. {
    9. printf("%d ", arr[i]);
    10. }
    11. printf("\n");
    12. }

    5.升级冒泡排序

    1.我们可以看出,每次我们进行完一趟排序后,未排序中最大(最小)的那个数就会被排到未排序的数的最后,因此我们没有必要去和那些已经排好序的数作比较,所以我们可以把单躺循环判断语句改写成j

    2.如果数组已经有序我们还在比较显然就会浪费大量的时间    可以看出,如果数组无序的话,那个未排序中最大(最小)的那个数就会被排到未排序的数的最后,期间一定会出现交换,而如果有序的话就一定不会出现交换。

    因此我们可以通过一个flaw变量来实现,每次进行新的一趟排序前,先将flaw变量初始化为1,一旦发生交换就令它为0,再在最外面根据flaw来判断是否发生了交换,如果发生了交换,那么数组依然无序,若是没有,则有序,结束函数

    6.升级版代码

    1. void BobbleSort(int*arr,int n)
    2. //传递数组和数组元素个数
    3. {
    4. int i = 0;
    5. int j = 0;
    6. for (i = 0; i < n; i++)
    7. //n次排序排n个数
    8. {
    9. int flaw = 1;
    10. for (j = 0; j < n -i- 1; j++)
    11. //j
    12. {
    13. if (arr[j] > arr[j + 1])
    14. //不断地进行比较,一遇到大的就进行交换,会将最大的数移动到数组的最后
    15. {
    16. Swap(&arr[j + 1], &arr[j]);
    17. flaw = 0;
    18. }
    19. }
    20. if (flaw == 1)
    21. {
    22. return;
    23. }
    24. }
    25. }

    7.升级版测试

    二、选择排序

    1.选择排序的原理

    选择排序十分的简单粗暴,就是在数组中找到最大值和最小值,然后把它们放到对应的位置,如果你想排升序最大值放右边,最小值放左边,排降序相反即可。 

    2.实现选择排序

    1.单躺排序

    第一趟排序我们找到最大值和最小值然后把它们放在对应的位置即可

    1. void SelectSort(int*arr,int n)
    2. {
    3. int max = 0;
    4. int min = 0;
    5. //max和min均储存下标
    6. int i = 0;
    7. for (i = 0; i < n; i++)
    8. {
    9. if (arr[max] < arr[i])
    10. {
    11. max = i;
    12. }
    13. if (arr[min] > arr[i])
    14. {
    15. min = i;
    16. }
    17. }
    18. Swap(&arr[0] = &arr[min]);
    19. //将最小值放到最前面
    20. Swap(&arr[n-1],&arr[max]);
    21. //将最大值放到最后
    22. }

    2.选择排序实现

    思考要排几趟,可以看出,每次都会将最大和最小的排到对应的位置,那么,循环差不多就是for(j=0;j

    思考细节,每比较一次,我们需要比较的区间就会缩小。所以应将查找最大最小的循环修改成for(i=j;i

    1. void SelectSort(int* arr, int n)
    2. {
    3. int i = 0; int j = 0;
    4. for (j = 0; j < n / 2; j++)
    5. {
    6. int max = j; int min = j;
    7. //max和min均储存下标
    8. for (i = j; i < n - j; i++)
    9. {
    10. if (arr[max] < arr[i])
    11. {
    12. max = i;
    13. }
    14. if (arr[min] > arr[i])
    15. {
    16. min = i;
    17. }
    18. }
    19. Swap(&arr[j], &arr[min]);
    20. //将最小值放到最前面
    21. Swap(&arr[n - 1 - j], &arr[max]);
    22. //将最大值放到最后
    23. }
    24. }

    3.测试

    4.修改

    为什么会出错呢,仔细思考,你会发现,若是max和j相等的话,j先和min进行交换,那么此时的j就不再是最大值的下标了,自然会出错,因此,当max和j相等的时候,应该在交换之后使max更新为min,更新到真正最大值的下标。

    1. void SelectSort(int* arr, int n)
    2. {
    3. int i = 0; int j = 0;
    4. for (j = 0; j 2; j++)
    5. {
    6. int max = j; int min = j;
    7. //max和min均储存下标
    8. for (i = j; i < n-j; i++)
    9. {
    10. if (arr[max] < arr[i])
    11. {
    12. max = i;
    13. }
    14. if (arr[min] > arr[i])
    15. {
    16. min = i;
    17. }
    18. }
    19. Swap(&arr[j], &arr[min]);
    20. //将最小值放到最前面
    21. if (j == max)
    22. //更新
    23. {
    24. max = min;
    25. }
    26. Swap(&arr[n - 1 - j], &arr[max]);
    27. //将最大值放到最后
    28. }
    29. }

     5.测试

    至此,冒泡排序和选择排序讲解完成,感谢各位友友的来访,祝各位友友前程似锦O(∩_∩)O

  • 相关阅读:
    Redis(10)----AOF持久化
    跨域问题的原理分析
    PLC无线通讯技术在汽车喷涂车间机械手臂上的应用
    链表大总结(王道加红皮书)
    ubuntu 18.04安装教程(详细有效)
    【Gitee】生成与配置SSH公钥
    Kubernetes入门 十六、访问控制
    全网最全谷粒商城记录_06、环境-使用vagrant快速创建linux虚拟机——2、vagrant镜像仓库、下载、安装、验证
    Python中关于文件的操作,一篇就够了
    华纳云:Linux文件不存在无法删除如何解决
  • 原文地址:https://blog.csdn.net/fq157856469/article/details/133513601