新手向 算法 希尔排序-yang
希尔排序(Shell Sort)简介
希尔排序是插入排序的改进版本,通过将数组分割为多个子序列进行插入排序,逐步缩小子序列的间隔,最终完成整体排序。其核心思想是减少逆序对,从而提升排序效率。时间复杂度通常为 O(n^{1.3}) 到 O(n^2),具体取决于间隔序列的选择。
希尔排序的实现步骤
选择间隔序列(Gap Sequence)
常见间隔序列选择:- 初始间隔为
n/2
,后续每次减半(希尔原始序列)。 - 更优的序列如Knuth序列:h = 3h + 1(1, 4, 13, 40...)。
- 初始间隔为
按间隔分组并插入排序
对每个间隔gap
,将数组分为gap
个子序列,分别进行插入排序。逐步缩小间隔直至1
当gap = 1
时,退化为标准插入排序,此时数组已基本有序,排序效率较高。
C++代码实现
//希尔排序 时间复杂度O(n^1.3~1.7) 空间复杂度O(1) 稳定性:不稳定
void Shell_Adjust(int arr[], int len, int gap)//以增量gap对传进来的数据arr,进行处理
{for (int i = gap; i < len; i++)//i即代表趟数,也代表这一趟待排序值的下标 //***{//提前干一个事:将带排序的值,拷贝给tmp,防止意外被覆盖掉int tmp = arr[i];int j = i - gap;//***for ( ; j >= 0; j-=gap)//具体控制这一趟中,已排序好的序列从右至左依次和待排序值进行比较//***{//比较if (arr[j] > tmp)//如果大于tmp,向后挪动一个位置{arr[j+gap] = arr[j];//***}else//如果小于等于tmp,则停下来{//将tmp挪回去(挪回到停下来的位置的后面break;}}//或者触底,则停下来arr[j + gap] = tmp;//***}
}
void Shell_Sort(int arr[], int len)
{int gap[] = { 5,3,1 };//提供一个增量数据for (int i = 0; i < sizeof(gap) / sizeof(gap[0]); i++)//控制的是趟数{Shell_Adjust(arr, len, gap[i]);//调用对应的单次处理函数}
}
关键点说明
- 间隔序列的选择:直接影响排序效率。Knuth序列优于希尔原始序列。
- 稳定性:希尔排序是不稳定的排序算法,相同元素可能在分组时交换顺序。
- 空间复杂度:O(1),属于原地排序算法。
示例测试
输入数组:{12, 34, 54, 2, 3}
调用 shellSort
后输出:{2, 3, 12, 34, 54}
优化方向
- 更优的间隔序列:如Sedgewick序列(1, 5, 19, 41...)可进一步提升效率。
- 结合其他排序:当数组接近有序时,可切换为插入排序以减少操作次数。