前言
以下内容是被验证可以有效理解希尔排序,代码也较容易理解。如果你发现还有很多需要增加的,欢迎留言。
为什么要单独写算法>排序算法这一系列,看过一些贴子普遍篇幅较长。看完还依旧云里雾里,难以直观理解原理及整个过程。代码永远是基于理解的基础上才能实现。
执行过程能动画展示需方便清晰,同时需具备单步调试,方便没理解的可以回看。
语言比较推荐c语言,高级语言库函数较多,人都有惰性思维,将自己置身于环境中训练也是至关重要。
感悟心得:初级阶段学习算法,在理解的基础上每天徒手2种算法。每种算法都是一种不同的思维方式,相信第一阶段坚持30天后会有不一样的收获。
实现原理
希尔排序(Shell Sort)是一种插入排序的改进版本,其核心思想是首先将待排序的数组按照一定的间隔分组,对每组数据进行插入排序,然后逐渐减小间隔,重复分组和排序的过程,直到间隔为1,此时整个数组被视为一个组,进行最后一次插入排序。希尔排序的增量序列选择是数学上的一个难题,但希尔最初建议的增量序列是{n/2, (n/2)/2, ..., 1},其中n是数组的长度。
希尔排序的详细过程可以概括为以下几个步骤:
-
初始化增量:选择一个初始增量
gap
,通常为数组长度的一半。如果数组长度为奇数,向下取整。 -
分组排序:将数组分为多个子组,每个子组包含间隔为
gap
的元素。对每个子组使用直接插入排序进行排序。 -
减小增量:减小增量
gap
,通常为gap/2
。重复步骤2,直到增量减至1。 -
最终排序:当增量为1时,整个数组被视为一个组,进行最后一次直接插入排序。
希尔排序的时间复杂度分析较为困难,因为它依赖于增量序列的具体形式。在特定情况下,希尔排序的时间复杂度约为O(n^1.3),在最坏情况下可能达到O(n^2)。希尔排序的空间复杂度为O(1),因为它只需常数个额外空间来存储增量和索引。希尔排序是不稳定的算法>排序算法,因为相同的关键字可能会在分组过程中改变它们的相对次序。
动画展示过程(Shell Sort)
Comparison Sorting Visualization
具体代码实现
#include <stdio.h>void shell_sort(int arr[], int len) {int i, j, gap;for (gap = len / 2; gap > 0; gap /= 2) {for (i = gap; i < len; i++) {int temp = arr[i];for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}arr[j] = temp;}}
}int main() {int arr[] = {12, 34, 54, 2, 3, 4, 34, 56, 7, 9, 10, 12};int len = (int) sizeof(arr) / sizeof(*arr);shell_sort(arr, len);for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
Q1:
A1: