• 基本算法-插入排序


    作者:翟天保Steven
    版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处


    前言

           本文介绍一种经典排序算法——插入排序,是入门级的排序算法之一。以下是本篇文章正文内容,包括算法简介、算法特点、算法实现和C++示例。

    一、插入排序简介

           插入排序法是将数组中的元素逐一与已排序好的数据进行比较,并将其放置在合适位置。例如,从小到大排序,第一个数据默认为已排序状态,第二个数据和第一个数据比较并调整位置,第三个数据与排序好的第二个数据比较,如果大于第二个数据,就原地放置,如果小于第二个数据,则再与第一个数据比,这样三个数据就排序好了,以此类推,直到所有的数据都插入到合适的位置,完成排序。

    二、算法特点

           1)最坏情况和平均情况需执行(n-1)+(n-2)+....+3+2+1=n(n-1)/2次,时间复杂度为O(n2);最好情况只需扫描一次即可,也就是本身已经排序好了,这样只执行了n-1次,时间复杂度为O(n)。和冒泡排序类似。

           2)由于插入排序为相邻两个数据相互比较而后决定是否互换位置,并不会改变原来排序的顺序,因此属于稳定排序法。

           3)只需要一个额外空间,空间复杂度很低。

           4)此排序法适用于大部分数据已经排过序的情况,也适用于往已排序数据库中添加新数据后再进行排序的情况。

           5)由于插入排序法会造成数据的大量迁移,因此建议在链表上使用。

    三、代码实现

           代码实现逻辑:

    1. 从第二个数开始插入,因此i的起始点是1;j是倒序比较的下标,从i-1开始直到0。
    2. 如果一开始result[j]<result[i],则不用进行下面的while循环,说明已经排序完毕了。
    3. 若result[j]>result[i],则进入while循环,这个循环干的事就是把比当前数大的值都往后排,所以有result[j+1]=result[j]和j--的操作;到了某个位置,当前数大于前一个数了,此时循环终止,将之前存的temp赋值在当前位置上,就相当于将其插入了。
    1. // 插入排序
    2. vector<int> InsertSort(vector<int> data)
    3. {
    4. // 拷贝
    5. vector<int> result = data;
    6. // 排序过程:
    7. int size = static_cast<int>(data.size());
    8. for (int i = 1; i < size; ++i)
    9. {
    10. int temp = result[i];
    11. int j = i - 1;
    12. while (j >= 0 && result[j] > temp)
    13. {
    14. result[j + 1] = result[j];
    15. j--;
    16. }
    17. result[j + 1] = temp;
    18. }
    19. return result;
    20. }

    四、C++示例

    1. #include <iostream>
    2. #include <iomanip>
    3. #include <vector>
    4. #include <string>
    5. using namespace std;
    6. // 展示当前顺序
    7. void Show(vector<int> data)
    8. {
    9. size_t size = data.size();
    10. for (size_t i = 0; i < size; ++i)
    11. cout << setw(4) << data[i];
    12. cout << endl;
    13. }
    14. // 插入排序
    15. vector<int> InsertSort(vector<int> data)
    16. {
    17. // 拷贝
    18. vector<int> result = data;
    19. cout << "插入排序:\n原始数据:\n";
    20. Show(result);
    21. // 排序过程:
    22. int size = static_cast<int>(data.size());
    23. for (int i = 1; i < size; ++i)
    24. {
    25. int temp = result[i];
    26. int j = i - 1;
    27. while (j >= 0 && result[j] > temp)
    28. {
    29. result[j + 1] = result[j];
    30. j--;
    31. }
    32. result[j + 1] = temp;
    33. cout << "第" << i << "次排序结果:\n";
    34. Show(result);
    35. }
    36. cout << "排序后结果:\n";
    37. Show(result);
    38. return result;
    39. }
    40. // 主函数
    41. int main()
    42. {
    43. vector<int> data = { 9,11,567,0,-2,4,2 };
    44. // 插入排序
    45. vector<int> result3 = InsertSort(data);
    46. system("pause");
    47. return 0;
    48. }

           效果图:

           综上所述,插入排序法是个比较基础的排序法,优点是往已排序的数据集合中插入新数据时,很方便省时,缺点就是对全乱的数据进行排序时挺慢的~

           如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

  • 相关阅读:
    基于Python实现的钢筋数量识别
    树莓派基础配置
    【手把手带你学JavaSE】第八篇:抽象类和接口
    html CSS 循环旋转的圆圈
    Unity -- 按钮的使用
    Leetcode219. 存在重复元素 II
    (过滤器)Filter和(监听器)listener
    你是怎么看待程序员不写注释这一事件的呢?
    如何做代码评审(code review)
    ubuntu18.04离线源制作
  • 原文地址:https://blog.csdn.net/zhaitianbao/article/details/125612359