• 直接选择排序


    目录

    一、算法简介

    1.排序思想

    2.优化思路

    二、算法实现

    1.代码实现

    2.测试用例即结果

    三、性能分析

    1.时间复杂度

    2.空间复杂度

    3.稳定性


    一、算法简介

    1.排序思想

    选择排序的思想就是通过遍历无序序列,每次从无序序列中选出最小(或最大)的元素,将其放到依次放到序列的起始(或末尾)位置,直到全部待排序的元素排序完成。

    流程演示:

    每次从待排序序列中选取最大元素,将其交换到待排序序列末尾,若最大元素本身就在末尾则不需要交换;待排序序列长度减一。经过n-1趟选择即可完成排序。

    2.优化思路

    在每次遍历待排序序列选取元素时,我们可以同时选取最大和最小两个元素,然后分别将其放到序列末尾和起始位置即可,这样每趟遍历我们可以一次性排好两个元素,从而提高算法效率。

    注意:

    采用此思路实现时需注意,当最小元素恰好在序列的最大元素待放入位置时,因为对最大元素进行放入后会改变最小元素位置,所有需要提前改变最小元素的标记位置为最大元素交换前的位置。

    示例:

    二、算法实现

    1.代码实现

    1. #include
    2. using namespace std;
    3. void ArryPrint(int* arr, int size) {//数组打印
    4. for (int i = 0; i < size; i++) {
    5. cout << arr[i] << ' ';
    6. }
    7. }
    8. void SelectSort(int* arr, int size) {//直接选择排序
    9. for (int i = 0; i < size - 1; i++) {//n-1趟排序,最后一个元素不需要再排序
    10. int maxPos = 0;
    11. for (int j = 0; j < size - i; j++) {//寻找待排序序列内最大元素的下标
    12. if (arr[j] > arr[maxPos]) {
    13. maxPos = j;
    14. }
    15. }
    16. if (maxPos != size - i - 1) {//若最大元素不在序列末尾,则交换到末尾
    17. swap(arr[size - i - 1],arr[maxPos]);
    18. }
    19. }
    20. }
    21. void SelectSortOP(int* arr, int size) {//直接选择排序优化版
    22. int begin = 0;//标记待排序序列区间
    23. int end = size - 1;
    24. while (begin < end) {//至少还有2个元素
    25. int minPos = begin;
    26. int maxPos = begin;
    27. int index = begin + 1;
    28. while (index <= end) {//选取待排序序列最大和最小元素
    29. if (arr[index] > arr[maxPos]) {
    30. maxPos = index;
    31. }
    32. if (arr[index] < arr[minPos]) {
    33. minPos = index;
    34. }
    35. index++;
    36. }
    37. if (minPos == end) {//若最小元素恰好在末尾,提前改变其标记位置
    38. minPos = maxPos;
    39. }
    40. if (maxPos != end) {//将最大元素交换到末尾
    41. swap(arr[maxPos], arr[end]);
    42. }
    43. if (minPos != begin) {//将最小元素交换到起始
    44. swap(arr[begin], arr[minPos]);
    45. }
    46. end--;
    47. begin++;
    48. }
    49. }
    50. void Test() {
    51. int arr[] = { 5,8,4,7,1,9,3,2,0 };
    52. int size = sizeof(arr) / sizeof(arr[0]);
    53. cout << "排序前:";
    54. ArryPrint(arr, size);
    55. //SelectSort(arr, size);
    56. SelectSortOP(arr, size);
    57. cout << endl << "排序后:";
    58. ArryPrint(arr, size);
    59. }
    60. int main() {
    61. Test();
    62. return 0;
    63. }

    2.测试用例即结果

    用例:int arr[] = { 5,8,4,7,1,9,3,2,0 }

    普通版本测试结果:

    优化版本测试结果:

     

    三、性能分析

    1.时间复杂度

     O(n^{2}):

    根据算法的实现思想和代码实现可知,直接选择排序内循环中代码的执行次数固定为\frac{n(n-1)}{2}次,与待排序序列的初始状态无关,时间复杂度计算只关心其最终量级,所以直接选择排序算法的时间复杂度为O(n^{2})。

    2.空间复杂度

    O(1):

    因为算法实现中除了用于标记元素位置的临时变量外,没有借助额外的复制空间,所以直接选择排序的空间复杂度为O(1)。

    3.稳定性

    不稳定:

    ​因为算法实现中,每次遍历待排序序列选取元素后,是将其放入到序列的最后位置,所以序列中相同元素位置靠前的先放入到序列末尾,靠后的元素后放入末尾,改变了其相对位置,所以直接选择排序不稳定。

    活动地址:CSDN21天学习挑战赛

  • 相关阅读:
    docker安装nginx1.20.2并配置nginx.conf
    Telegram 正式引入国产小程序技术
    postgresql14-表的管理(四)
    linux套接字选项API
    Kubeadm方式快速搭建K8S集群1.20版本
    Linux常见基本指令合集及其效果展示
    哪些场景会产生OOM?
    java计算机毕业设计ssm健达企业项目管理系统
    吐血整理,Jmeter服务端性能测试-线程阻塞问题案例分析(超细)
    02-React中JSX存在的意义
  • 原文地址:https://blog.csdn.net/m0_63020222/article/details/126180207