算法导论之插入排序

逃离我推掉我的手 2022-03-21 11:10 296阅读 0赞

比如我们对下面的进行排序,排序过程如下












5 2 4 6 1 3











2 5 4 6 1 3











2 4 5 6 1 3

-—————————————————————-每次进行比较2位,然后插到合适的位置












1 2 3 4 5 6

下面先附上代码

  1. //
  2. // main.cpp
  3. // 算法导论
  4. //
  5. // Created by SJCHEN on 2019/1/19.
  6. // Copyright © 2019 SJCHEN. All rights reserved.
  7. //
  8. #include <iostream>
  9. #include <string>
  10. using namespace std;
  11. int len = 0;
  12. void InsertSort(int arr[])
  13. {
  14. for (int j = 1; j < len; ++j) {
  15. int key = arr[j];
  16. int i = j - 1;
  17. while (i >= 0 && arr[i] < key) {
  18. arr[i + 1] = arr[i];
  19. i = i - 1;
  20. }
  21. arr[i + 1] = key;
  22. }
  23. }
  24. int main()
  25. {
  26. int arr[] = {5,2,4,6,1,3};
  27. len = sizeof(arr) / sizeof(arr[0]);//计算数组的长度
  28. InsertSort(arr);
  29. for (int i = 0; i < len; i++) {
  30. cout << arr[i] << " ";
  31. }
  32. cout << endl;
  33. return 0;
  34. }



























5 2 4 6 1 3
i j        
  key        

i>=0 && arr[i] > key




























2 5 4 6 1 3
arr[i+1] = key          
           

我们可以看到插入排序的时间复杂度为O(n^2), 我们有没有什么方法可以改进呢?、

答案就是二分插入排序。(如果二分排序不懂的话,可以去看下我前面写的),我们不在一个一个的比较大小,而是在前面有序的情况下直接进行 二分查找,

二分插入排序的时间复杂度为O(nlgn)。

  1. //
  2. // main.cpp
  3. // 算法导论
  4. //
  5. // Created by SJCHEN on 2019/1/19.
  6. // Copyright © 2019 SJCHEN. All rights reserved.
  7. //
  8. #include <iostream>
  9. using namespace std;
  10. int arr[] = {1,5,2,7,6,8,9,3};
  11. int len = sizeof(arr) / sizeof(arr[0]);
  12. int Binary(int start, int end, int val)
  13. {
  14. for (int j = start; j <= end; j++)
  15. if (arr[j] > val)//和二分查找不同,这里是大于(升序)
  16. return j;
  17. return -1;
  18. }
  19. int BinarySearch(int start, int end, int val)
  20. {
  21. if (start == 0 && end == 0 && arr[0] > val)//特殊情况,只有一位元素
  22. return 0;
  23. if (start < end) {
  24. int mid = (start + end) / 2;
  25. if (arr[mid] > val) {//递归左边
  26. BinarySearch(start, mid, val);
  27. return Binary(start, mid, val);
  28. }
  29. else {//递归右边
  30. BinarySearch(mid + 1, end, val);
  31. return Binary(mid + 1, end, val);
  32. }
  33. }
  34. return -1;
  35. }
  36. void BinaryInsertSort(int arr[])
  37. {
  38. for (int j = 1; j < len; j++) {
  39. int key = arr[j];
  40. int i = j - 1;
  41. int k = BinarySearch(0,i,key);
  42. if (k != -1) {
  43. for (int s = i; s >= k; s--)
  44. arr[s + 1] = arr[s];
  45. arr[k] = key;
  46. }
  47. }
  48. }
  49. int main()
  50. {
  51. BinaryInsertSort(arr);
  52. for (int i = 0; i < len; i++) {
  53. cout << arr[i] << " ";
  54. }
  55. cout << endl;
  56. return 0;
  57. }

发表评论

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

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

相关阅读

    相关 排序算法插入排序

    \[插入排序-普通插入排序\] 1.算法思想 将元素a视为基序列,遍历数组将元素a右边的元素依次插入序列中,找到比自己小的数置于其后,保证序列一直处于已排序的状态

    相关 算法导论学习插入排序

    《算法导论》买了好久了,基本上没怎么看,最近思想上有了转变,觉得学习才是王道。准备重新拾起来学习,下面我就《算法导论》中的排序算法中的 插入排序做了个c++的简单实现,附加解

    相关 一头扎进算法导论-插入排序

    定义:直接插入排序是一种简单的排序方法,她的基本思想是依次将每个记录插入到一个已排好序的有序表中去,从而得到一个新的、记录数增加1的有序表,就好比斗地主抓牌排序的这么一个过程

    相关 算法导论归并排序

    归并排序的思想就是分治法; 分治法:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题。 分治模式在每层递归时都有三个步骤: 一,分解原问题