排序_插入排序_直接插入排序

简单直观的排序方法。

基本思想:每次将一个待排序的记录 按其关键字大小 插入前面已排好序的子序列。直到全部插入记录完成。

可以引申出三个重要的排序算法:直接插入排序,折半插入排序,希尔排序。

 

直接插入排序(最简单,最直观):

 1 void InsertSort(ElemType A[] , int n){
 2     int i , j ;
 3     for (i = 2 ; i <= n ; i++)                //依次将A[2]-A[n]插入前面已经排好的序列
 4         if (A[i] < A [i - 1]){                //如果A[i]关键码小于其前驱,将A[i]插入有序表
 5             A[0] = A[i];            //复制为哨兵,A[0]不存放元素
 6             for(j = i -1 ; A[0] < A[j] ; --j)        //从后往前查找待插入位置
 7                 A[j+1] = A[j] ;         //比待插入元素大的向后挪
 8             A[j+1] = A[0];            //复制到插入位置
 9         }
10 }

有一个“哨兵”的概念,可以理解为,一个空的位置,以前可能写代码时直接int定义一个,这次直接在数组开始设置。

说一下自己的思路:

第一个元素A[1]其实已经是默认有序的(A[0]是哨兵,不管A[0]),代码第3行从i = 2开始,当发现它比它的前驱小的时候(因为我们这个是从小到大),它的位置应该 至少在它前驱之前(也就是说需要进行位置替换),我们就

1,先把它替换成哨兵(代码第四行,第五行)(为了后面方便,也节省空间,减少代码冗余)

2,现在开始判断它应该在哪(程序第6,7行),所有比他大的都要往后挪一位

3,最后找到自己的位置(第8行)

性能分析:

空间效率:仅用了常数个辅助单元,因而空间复杂度为O(1)。

时间效率:最好情况下,表中元素有序,时间复杂度O(n)。最坏情况下,表中元素刚好与排序结果中的元素顺序相反,比较次数最大,为(2+3+...+n)次,移动次数也最大,(3+4+...+i+1)次。平均情况下,约为n*n/4,即时间复杂度为O(n²)。

稳定性:由于每次插入元素时,总是从后向前比较再移动,所以不会出现相同元素相对位置发生变化的情况,即直接插入排序是一个稳定的排序方法。

适用性:直接插入排序算法适用于顺序存储和链式存储的线性表。

(大部分排序算法都适用于顺序存储的线性表)

posted @ 2021-08-25 18:02  KeithTee  阅读(35)  评论(0编辑  收藏  举报