希尔排序——交换版和移动版
简单介绍:
希尔排序(Shell's Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。该方法因 D.L.Shell 于 1959年提出而得名。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰被分成一组,算法便终止。
图解:
直接插入排序:
1 public class InsertSort { 2 public static void main(String[] args) { 3 int[] arr = {2, 1, 4, 7, 5, 3, 6}; 4 insertSort(arr); 5 for (int i = 0; i < arr.length; i++) { 6 System.out.print(arr[i] + "\t"); 7 } 8 } 9 10 public static void insertSort(int[] arr) { 11 int count = 0; 12 // 默认一个数是排好序的,所以从i = 1开始 13 for (int i = 1; i < arr.length; i++) { 14 // 将当前需要插入的数保存起来 15 int temp = arr[i]; 16 // j是i前面数的下标 17 int j = i - 1; 18 while (j >= 0 && arr[j] > temp) { 19 count++; 20 arr[j + 1] = arr[j]; 21 // 继续向前搜索 22 j--; 23 } 24 // 出了while循环,此时j + 1正是插入的位置 25 arr[j + 1] = temp; 26 } 27 System.out.println(count); 28 } 29 }
希尔排序交换版
1 public class ShellSortExchange { 2 public static void main(String[] args) { 3 int[] arr = {2, 9, 8, 7, 6, 4, 5, 1, 3, 0}; 4 shellSort(arr); 5 } 6 7 public static void shellSort(int[] arr) { 8 int count = 0; 9 // 分组,对每一组进行局部排序 10 for (int gap = arr.length / 2; gap >= 1; gap /= 2) { 11 // 分几组,就从第一组的最后一个元素开始遍历 12 for (int i = gap; i < arr.length; i++) { 13 int j = i - gap; 14 while (j >= 0 && arr[j] > arr[j + gap]) { 15 int temp = arr[j]; 16 arr[j] = arr[j + gap]; 17 arr[j + gap] = temp; 18 j -= gap; 19 } 20 } 21 System.out.println("第" + (++count) + "次循环后:" + Arrays.toString(arr)); 22 } 23 } 24 }
希尔排序移动版
1 package com.lzp.util.sort; 2 3 import java.util.Arrays; 4 5 /** 6 * Created by Administrator on 2021/3/19. 7 * 希尔排序 8 * 移动版 9 */ 10 public class ShellSortMove { 11 public static void main(String[] args) { 12 int[] arr = {4, 2, 1, 5, 3, 8, 7, 6}; 13 shellSort(arr); 14 System.out.println(Arrays.toString(arr)); 15 } 16 17 public static void shellSort(int[] arr) { 18 // 先确定增量,而且增量每次减半,直到减到0就全部排好序了 19 for (int gap = arr.length / 2; gap >= 1; gap /= 2) { 20 // 找每次分组后的第一组中的最后一个元素,就是针对每一组先进行排序(局部排序) 21 for (int i = gap; i < arr.length; i++) { 22 // 遍历该组,让该组的最后一个元素跟其所在组的前面其他元素进行依次比较 23 int j = i - gap; 24 // 先将该组的最后一个元素保存到temp变量中,因为这是移动元素,而不是交换元素 25 int temp = arr[i]; 26 while (j >= 0 && arr[j] > temp) { 27 // 如果前面的比后面的大,就覆盖后面的 28 arr[j + gap] = arr[j]; 29 // 指针继续向前移动gap 30 j -= gap; 31 } 32 // 程序运行到这里,while循环结束,表示此时指针指向的后一个位置才是temp最终应该处于的位置,所以指针j要向后移动gap 33 arr[j + gap] = temp; 34 } 35 } 36 } 37 }
测试80000数据量:
直接插入排序消耗的时间
希尔排序所消耗的时间
由此可以看出希尔排序比直接插入排序的效率高了很多
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能