希尔排序(Shell Sort)思想
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序的基本思想是将整个待排序的记录序列分割成若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。
主要思想:
- 分组排序:将数组按某个增量分为若干个子序列,分别进行插入排序。
- 缩小增量:不断缩小增量(通常是将增量减半),重复步骤1,直到增量为1。
- 最终排序:当增量为1时,进行一次普通的插入排序。
时间复杂度
- 最坏情况时间复杂度:根据不同的增量序列,时间复杂度可能不同,常见的是 (O(n^2)) 或 (O(n \log^2 n))。
- 平均时间复杂度:一般为 (O(n \log n)) 到 (O(n \log^2 n)) 之间。
- 最好情况时间复杂度:(O(n \log n))。
Java 实现
public class ShellSort {
// 希尔排序方法
public void shellSort(int[] arr) {
int n = arr.length;
// 选择增量序列,这里使用简单的 n/2
for (int gap = n / 2; gap > 0; gap /= 2) {
// 从 gap 开始,逐个对每个元素进行插入排序
for (int i = gap; i < n; i++) {
int key = arr[i];
int j = i;
// 对每个子序列进行插入排序
while (j >= gap && arr[j - gap] > key) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = key;
}
}
}
// 打印数组方法
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
// 主方法
public static void main(String[] args) {
ShellSort sorter = new ShellSort();
int[] arr = { 12, 34, 54, 2, 3 };
System.out.println("Unsorted array:");
printArray(arr);
sorter.shellSort(arr);
System.out.println("\nSorted array:");
printArray(arr);
}
}
代码解析
- 增量序列:外层循环使用
gap
来控制增量序列,初始值为数组长度的一半,然后逐步减半,直到gap
为1。 - 分组排序:对于每一个增量
gap
,对所有元素进行插入排序。 - 插入排序:内层循环执行插入排序,与插入排序的唯一不同是元素比较和移动的距离是
gap
而不是1。
总结
希尔排序通过将数组分组进行排序,有效地减少了数据移动的次数,从而提高了排序效率。虽然它的最坏情况时间复杂度较高,但在实际应用中通常表现良好,特别是对于中小规模的数据集。希尔排序的性能高度依赖于增量序列的选择,使用合适的增量序列可以显著提升排序性能。