排序_插入排序_直接插入排序
简单直观的排序方法。
基本思想:每次将一个待排序的记录 按其关键字大小 插入前面已排好序的子序列。直到全部插入记录完成。
可以引申出三个重要的排序算法:直接插入排序,折半插入排序,希尔排序。
直接插入排序(最简单,最直观):
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²)。
稳定性:由于每次插入元素时,总是从后向前比较再移动,所以不会出现相同元素相对位置发生变化的情况,即直接插入排序是一个稳定的排序方法。
适用性:直接插入排序算法适用于顺序存储和链式存储的线性表。
(大部分排序算法都适用于顺序存储的线性表)