vlambda博客
学习文章列表

【从零开始的算法指南】大概是代码注释最详细的希尔排序笔记

基本思想

 将排序表分割成若干个字表L(i, i + d, i + 2d, ..., i + kd)对每个子表分别进行插入排序。下一趟分割将d减小,使得部分有序的子表变大。当d = 1时,排序表全表有序。d通常被成为步长,d可以根据具体情况进行取值,不过一般情况第一趟一般取表长的一半。

算法代码

  
    
    
  
void sort_shell ( vector < int > & A , int n ) { //传入排序表和表长 n = A.size()
for ( int d = n / 2 ; d >= 1 ; d = d / 2 ) //设置每趟排序的步长
{
for ( int i = 1 + d ; i <= n ; ++ i ) { //一趟排序
if ( A [ i ] < A [ i - d ] ) { //将A[i]插入有序部分
A
[ 0 ] = A [ i ] ; //暂存在A[0]
for ( int j = i - d ; j > 0 && A [ 0 ] < A [ j ] ; j -= d ) { //找到插入位置
A
[ j + d ] = A [ j ] ;

}
A
[ j + d ] = A [ 0 ] ; //完成插入操作
}
}
}

}

时间复杂度:希尔排序的时间复杂度依赖于步长序列的函数,计算比较困难,约为O(N^1.3),最坏情况下仍为O(N^2)

空间复杂度:O(1)只需要常数个单位,暂存比较元素

稳定性:不稳定,如果相同关键字的元素没有被分到同一个子表,那么他们相对的先后次序就可能会改变


觉得文章不错有所帮助的话,记得帮我点个赞,也可以关注下我!