希尔排序——交换版和移动版

简单介绍:
希尔排序(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数据量:

直接插入排序消耗的时间

希尔排序所消耗的时间

 由此可以看出希尔排序比直接插入排序的效率高了很多

posted @   没有你哪有我  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· 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 加持,客户体验更智能
点击右上角即可分享
微信分享提示