• 8.2 简单排序算法 (1) 插入排序 (2) 选择排序 (3) 冒泡排序 8.3 线性时间排序(1) 桶排序 (2) 计数排序 (3) 基数排序*(附代码)


    8.2 简单排序算法

    以下三种排序算法的时间复杂度是 O(n^2)。在这三种排序算法中,比较好的是插入排序。

    (1) 插入排序!

    基本思想:假设前 i 个元素已经排好序,然后把第 i+1 个元素插入到合适的位置上。

    1. void ins_sort(int *a, int start, int end)
    2. {
    3. int j,k;
    4. for (int i=start+1; i<end; i++)
    5. {
    6. for (k=a[i],j=i-1; k<a[j] && j>=start; j--)
    7. a[j+1]=a[j];
    8. a[j+1]=k;
    9. }
    10. }

    (2) 选择排序!

    基本思想:处理第 i 个元素时,找到它后面所有数的最小值。如果这个最小值比它小,就互相交换。

    1. void swap_sort(int *a, int start, int end)
    2. {
    3. int temp;
    4. for (int i=start; i<end; i++)
    5. for (int j=i+1; j<end; j++)
    6. if (a[i]>a[j])
    7. temp=a[i],a[i]=a[j],a[j]=temp;
    8. }

    (3) 冒泡排序!
     

    基本思想:对相邻两个元素进行比较,并将较小的数放到前面。重复 n 组即可完成排序。

    1. void bubble_sort(int *a, int start, int end)
    2. {
    3. int temp;
    4. for (int i=start; i<end; i++)
    5. for (int j=end; j>i; j--) // 从start到i,在“冒泡”过程中,元素已经排好序。
    6. if (a[j-1]>a[j])
    7. temp=a[j-1], a[j-1]=a[j], a[j]=temp;
    8. }

    8.3 线性时间排序 

    以下几种排序算法的时间复杂度为 O(n),因为它们使用的是基于数字本身的排序。

    (1) 桶排序!

    基本思想:设计 M 个桶,根据元素本身进行分配。因为 M 个桶是按顺序排列的,所以分配元素之后元素也会按顺序排列。
    待排序的数据范围不太大时可以考虑这样排序(比如1~1000可以考虑,而1~100000就必须用快速排序)。
    下面假设每个数都位于区间[1, M]。

    1. int cnt[M];
    2. memset(cnt,0,sizeof(cnt));
    3. for (int i=0; i<N; i++)
    4. cnt[a[i]]++;
    5. // 从cnt[0]开始挨个列举就行了。例如
    6. for (int i=0; i<M; i++)
    7. while ((cnt[i]--)>0)
    8. cout<<i<<" ";

    (2) 计数排序

    基本思想:对于序列中的每一元素 x,确定序列中小于 x 的元素的个数。下面假设每个数都位于区间[1, m]。

    1. int a[N], b[N], cnt[M];
    2. ……
    3. memset(cnt,0,sizeof(cnt));
    4. for (int i=0;i<n;i++) cnt[a[i]]++;
    5. for (int i=1;i<M;i++) cnt[i]+=cnt[i-1];
    6. for (int i=n-1;i>0;i--)
    7. {
    8. b[cnt[a[i]]] = a[i];
    9. cnt[a[i]]--;
    10. }
    11. // 输出结果
    12. for (int i=0;i<n;i++) cout<<b[i]<<' ';

    (3) 基数排序*

    基本思想:对 n 个元素依次按 k,k-1,...1 位上的数字进行桶排序。

    1. int tmp[N], cnt[10];
    2. int n;
    3. int maxbit(int *data, int n) // 辅助函数,求数据的最大位数
    4. {
    5. int d = 1; // 保存最大的位数
    6. int p =10;
    7. for (int i = 0;i < n; i++)
    8. while (data[i] >= p)
    9. p *= 10, d++;
    10. return d;
    11. }
    12. void radixsort(int *data, int n) // 基数排序
    13. {
    14. int d = maxbit(data,n);
    15. int i,j,k;
    16. int radix = 1;
    17. for (i = 1; i<= d;i++) // 进行d次排序
    18. {
    19. for (j = 0;j < 10;j++)
    20. cnt[j] = 0; // 每次分配前清空计数器
    21. for (j = 0;j < n; j++)
    22. {
    23. k = (data[j]/radix)%10; // 统计每个桶中的记录数
    24. cnt[k]++;
    25. }
    26. for (j = 1;j < 10;j++)
    27. cnt[j] = cnt[j-1] + cnt[j]; // 将tmp中的位置依次分配给每个桶
    28. for (j = n-1;j >= 0;j--) // 将所有桶中记录依次收集到tmp中
    29. {
    30. k = (data[j]/radix)%10;
    31. cnt[k]--;
    32. tmp[cnt[k]] = data[j];
    33. }
    34. for (j = 0;j < n;j++) // 将临时数组的内容复制到data中
    35. data[j] = tmp[j];
    36. radix = radix*10;
    37. }
    38. }

  • 相关阅读:
    使用OpenCV进行简单图像分割的3个步骤
    HTML显示中文空格字符,&emsp;一个中文字符,&ensp;半个中文字符
    Android 12(S) 图像显示系统 - 解读Gralloc架构及GraphicBuffer创建/传递/释放(十四)
    1.HTML中网页介绍
    Flask 入门
    CG Magic分享如何解决Vray渲染器使用不了的问题?
    调试 WebSocket API 技巧分享
    线程安全问题的产生条件、解决方式
    steam搬砖项目的核心内容解答
    第四章 重载&访问修饰符&静态&常用类 ② 代码
  • 原文地址:https://blog.csdn.net/zhengheda/article/details/125552335