插入排序—直接插入排序(Straight Insertion Sort)

简介: 基本思想: 将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插插入到已入,直至整个序列有序为止。 要点:设立哨兵,作为临时存储和判断数组边界之用。

基本思想:

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插插入到已入,直至整个序列有序为止。

要点:设立哨兵,作为临时存储和判断数组边界之用。

直接插入排序示例:

 

如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

直接插入排序(straight insertion sort)的做法是:
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
 
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
 
直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。
哨兵的作用



算法中引进的附加记录R[0]称监视哨或哨兵(Sentinel)。

哨兵有两个作用:

① 进人查找(插入位置)循环之前,它保存了R[i]的副本,使不致于因记录后移而丢失R[i]的内容;

② 它的主要作用是:在查找循环中"监视"下标变量j是否越界。一旦越界(即j=0),因为R[0].可以和自己比较,循环判定条件不成立使得查找循环结束,从而避免了在该循环内的每一次均要检测j是否越界(即省略了循环判定条件"j>=1")。

注意:

① 实际上,一切为简化边界条件而引入的附加结点(元素)均可称为哨兵。

【例】单链表中的头结点实际上是一个哨兵

② 引入哨兵后使得测试查找循环条件的时间大约减少了一半,所以对于记录数较大的文件节约的时间就相当可观。对于类似于排序这样使用频率非常高的算法,要尽可能地减少其运行时间。所以不能把上述算法中的哨兵视为雕虫小技,而应该深刻理解并掌握这种技巧。

  

 

算法的实现:

 
#include<iostream>
using namespace std;
int  main()
{
     int  a[]={ 98 , 76 , 109 , 34 , 67 , 190 , 80 , 12 , 14 , 89 , 1 };
     int  k=sizeof(a)/sizeof(a[ 0 ]);
     int  j;
     for ( int  i= 1 ;i<k;i++) //循环从第2个元素开始
     {
         if (a[i]<a[i- 1 ])
         {
             int move =a[i];
             for (j=i- 1 ;j>= 0  && a[j]>move;j--)//a[j]若小于要挪动的数,则是循环终止的条件
             {
                 a[j+ 1 ]=a[j];//将a[i]前元素向后挪动一个
             }
             a[j+ 1 ]=move; //此处就是a[j+1]=move;
         }
     }
     for ( int  f= 0 ;f<k;f++)
     {
         cout<<a[f]<< "  " ;
     }
     return  0 ;
}

 

效率:

时间复杂度:O(n^2).

其他的插入排序有二分插入排序,2-路插入排序。

相关文章
|
7月前
|
搜索推荐 算法 Java
sort-01-bubble sort 冒泡排序算法详解
这是一个关于排序算法的系列文章摘要。作者整理了10种不同的排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序和大文件外部排序。文章详细介绍了冒泡排序的工作原理、流程,并提供了代码实现,强调了在实现中考虑的改进点,如统一接口、实用性增强和日志输出。此外,还提供了一个排序接口和工具类以方便使用,并通过测试代码和日志展示了排序过程。整个系列旨在帮助读者理解和掌握排序算法。相关代码已开源在GitHub。
|
7月前
|
存储
归并排序 merge_sort
归并排序 merge_sort
31 0
|
7月前
|
搜索推荐 算法 Java
sort-08-counting sort 计数排序
这是一个关于排序算法的系列文章摘要。文章详细介绍了多种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序。计数排序是一种线性时间复杂度的稳定排序算法,由 Harold H. Seward 在1954年提出。基础版计数排序通过创建一个与最大元素等长的新数组来统计每个元素出现的次数,然后填充排序结果。改良版则考虑了空间浪费问题,通过找出最小值来减少数组长度。此外,还提出了使用 TreeMap 来扩展排序算法以适应非数字元素的情况。
|
7月前
|
搜索推荐 算法 Java
sort-02-QuickSort 快速排序到底快在哪里?
这是一个关于排序算法的系列文章的摘要。文章详细介绍了各种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及处理大文件的外部排序。特别强调了快速排序,它是1959年由Tony Hoare发明的,平均时间复杂度为O(n log n),优于其他如合并排序和堆排序。快速排序采用分而治之的策略,选取基准元素,通过分区操作将数组分成两部分,然后递归地对这两部分进行排序。文章还通过示例和Java代码解释了快速排序的步骤和实现。最后,提供了开源项目的链接,供读者进一步学习和研究。
|
存储 搜索推荐 算法
计数排序(Counting Sort)详解
计数排序(Counting Sort)是一种非比较排序算法,其核心思想是通过计数每个元素的出现次数来进行排序,适用于整数或有限范围内的非负整数排序。这个算法的特点是速度快且稳定,适用于某些特定场景。在本文中,我们将深入探讨计数排序的原理、步骤以及性能分析。
280 1
计数排序(Counting Sort)详解
|
算法 搜索推荐
经典算法之折半插入排序(Binary Insertion Sort)
经典算法之折半插入排序(Binary Insertion Sort)
341 0
2-路插入排序(Two-Way Insertion Sort)
算法介绍 算法描述 算法分析 代码实现 参考
|
存储 算法 搜索推荐
|
搜索推荐 算法 数据可视化
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
122 0