十七、自己动手实现排序算法(5)-------- “ Shell Sort 希尔排序 ”

本文介绍了希尔排序的原理和步骤,通过增量序列将待排序序列分组进行直接插入排序,最后提供两种Java代码实现,并有希尔排序的原理图辅助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考文章:

https://www.cnblogs.com/guoyaohua/p/8600214.html                  十大经典排序算法最强总结(含JAVA代码实现)

https://github.com/liuyubobobo/Play-with-Algorithms/blob/master/02-Sorting-Basic/Course%20Code%20(Java)/Optional-03-Shell-Sort/src/bobo/algo/ShellSort.java

https://mp.weixin.qq.com/s/sW0-YjOJELdMImtCo7hisQ                希尔排序就这么简单


希尔排序分析:

平均时间复杂度最好情况最坏情况空间复杂度排序方式稳定性
O(n*logn)O(n*log2 n)O(n*log2 n)O(1)In-place不稳定

希尔排序原理:

          我们来看下希尔排序的基本步骤,在此我们选择增量gap=length/2,缩小增量继续以gap = gap/2的方式,这种增量选择我们可以用一个序列来表示,{n/2,(n/2)/2...1},称为增量序列。希尔排序的增量序列的选择与证明是个数学难题,我们选择的这个增量序列是比较常用的,也是希尔建议的增量,称为希尔增量,但其实这个增量序列不是最优的。此处我们做示例使用希尔增量。

 

希尔排序算法描述:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,具体算法描述:

  • 选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
  • 按增量序列个数k,对序列进行k 趟排序;
  • 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

 

希尔排序原理图:

 

 

Java 代码实现:

代码一:


package com.sorting.algorithm;
	
public class ShellSort {
	
	 public static void sort(Comparable[] arr){

	        int n = arr.length;

	        // 计算 increment sequence: 1, 4, 13, 40, 121, 364, 1093...
	        int h = 1;
	        while (h < n/3) h = 3*h + 1;

	        while (h >= 1) {

	            // h-sort the array
	            for (int i = h; i < n; i++) {

	                // 对 arr[i], arr[i-h], arr[i-2*h], arr[i-3*h]... 使用插入排序
	                Comparable e = arr[i];
	                int j = i;
	                for ( ; j >= h && e.compareTo(arr[j-h]) < 0 ; j -= h)
	                    arr[j] = arr[j-h];
	                arr[j] = e;
	            }

	            h /= 3;
	        }
		}

		public static  void printArr(Comparable[] array){
			for (int i = 0; i < array.length; i++) {
				if(i != array.length-1)
					System.out.print(array[i] + ",");
				else
					System.out.println(array[i]);
			}
			System.out.println();
		}
		
		public static void main(String[] args) {
			Comparable[] array = { 58,36,70,22,88,64,1,32 };
			System.out.println("排序之前:");
			printArr(array);
			System.out.println("-------------------------------");
			
			System.out.println("排序过程");
			sort(array);
			
			System.out.println("-------------------------------");
			System.out.println("排序之后:");
			printArr(array);
			
		}

}

 

代码二:


package com.sorting.algorithm;
	
public class ShellSort2 {
	
	public static int[] shellSort(int[] array) {
        int len = array.length;
        int temp, gap = len / 2;
        while (gap > 0) {
            for (int i = gap; i < len; i++) {
                temp = array[i];
                int preIndex = i - gap;
                while (preIndex >= 0 && array[preIndex] > temp) {
                    array[preIndex + gap] = array[preIndex];
                    preIndex -= gap;
                }
                array[preIndex + gap] = temp;
            }
            gap /= 2;
        }
        return array;
    }

	public static  void printArr(int[] array){
		for (int i = 0; i < array.length; i++) {
			if(i != array.length-1)
				System.out.print(array[i] + ",");
			else
				System.out.println(array[i]);
		}
		System.out.println();
	}
	
	
	public static void main(String[] args) {
		int[] array = { 58,36,70,22,88,64,1,32 };
		System.out.println("排序之前:");
		printArr(array);
		System.out.println("-------------------------------");
		
		System.out.println("排序过程");
		shellSort(array);
		
		System.out.println("-------------------------------");
		System.out.println("排序之后:");
		printArr(array);
		
	}
	
}

 

 

希尔排序代码测试:

 

代码一:

 

代码二:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值