Java-希尔排序

希尔排序又叫分组插入排序、缩小增量排序。

它通过比较相距一定间隔的元素来工作;各趟比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一趟比较为止。

简单的说就是先将整个序列分割成若干子序列(由相隔某个增量的元素组成),分别进行插入排序。然后依次缩减增量再进行排序,待整个序列中元素基本有序时,再对全体元素就行一次插入排序(因为此时整个序列已经基本有序了,用插入排序效率比较高,子序列排序时也是这个道理吧)。

public static void shellSort(int[] a){
	if(a==null){
		return;
	}

	int n = a.length;
	//确定增量序列为:n/2,2/4,...,1
	for(int gap=n/2; gap>0; gap /=2){

		for(int i=0; i<gap; i++){
			//对每个子序列插入排序
			for(int j=i+gap; j<n; j+=gap){
				int temp = a[j];
				////注意这的条件,k>=0并且a[k]>temp,若写成k>0那么第一个元素就没参加排序了
				for(int k=j-gap; k>=0&&a[k]>temp;k-=gap){
					a[k+gap] = a[k];
					a[k] = temp;
				}

			}
		}
	}
}

希尔排序的时间复杂度比O(N^2)要好,因为它一轮排序时对一些相距较远的元素进行了交换。

虽然每个子序列的排序是插入排序,并且插入排序是稳当的,但是在不同子序列的插入排序过程中,大小相同的元素可能在各自的插入排序中移动,导致了整体的稳定性被打破,所以希尔排序也是不稳定的啦。

时间: 2024-11-04 17:02:29

Java-希尔排序的相关文章

java希尔排序算法

原文:java希尔排序算法 代码下载地址:http://www.zuidaima.com/share/1550463279090688.htm 希尔排序算法的基本思想是:先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组内进行直接插人排序:然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<-<d2<d1),即所有记录放在同一组中进行直接插入排序为止.该方法实质上是一种

排序算法之 Java希尔排序算法

package net.qh.test.sort; import java.util.ArrayList; import java.util.Calendar; import java.util.List; /** * Created by Administrator on 2016/03/01. */ public class Shell { public int[] sort(int[] arr){ if ( arr == null || arr.length <= 1 ){ return

Java希尔排序

希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法. 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序. 算法步骤: 1)选择一个增量序列t1,

Hark的数据结构与算法练习之希尔排序

算法说明 希尔排序是插入排序的优化版. 插入排序的最坏时间复杂度是O(n2),但如果要排序的数组是一个几乎有序的数列,那么会降低有效的减低时间复杂度. 希尔排序的目的就是通过一个increment(增量)来对数列分组进行交换排序,最终使数列几乎有序,最后再执行插入排序,统计出结果. 通过increment=n/2, 也就是如果9个数的话,增量为4,2,1.   如果是20个数的话,增量就是10,5,2,1.  当increment为1时,其实对几乎有序的数列进行插入排序啦啦. 时间复杂度 O(n

【算法拾遗(java描述)】--- 插入排序(直接插入排序、希尔排序)

插入排序基本思想 每次将一个待排序的记录按其关键字大小插入到前面已经拍好序的子文件的适当位置,直到全部记录插入完成为止. 直接插入排序 基本思想 直接插入排序的基本操作是将一个记录插入到已排好序的有序表中,从而得到一个新的有序表.即假设待排序的记录存放在数组R[1······n]中,排序过程中,R被分成两个子区间R[1······i]和R[i+1······n],其中,R[1······i]是已经排好序的有序区:R[i+1······n]是当前未排序的部分.将当前无序区的第一个记录R[i+1]插

Java排序算法(四):希尔排序

[基本思想] 将原本有大量记录数的记录进行分组,分割成若干个子序列,此时每个子序列待排序的记录个数就比较少了,然后在这些子序列内分别进行直接插入排序,当整个序列都基本有序时,再对全体记录进行一次直接插入排序. 所谓的基本有序,就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间,像{2, 1, 3, 6, 4, 7, 5, 8, 9}这样可以称为基本有序了. [java实现] public class ShellSort { public static void main(String

算法-java代码实现希尔排序

希尔排序 第8节 希尔排序练习题 对于一个int数组,请编写一个希尔排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组.保证元素小于等于2000. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] Java (javac 1.7) 代码自动补全 1 import java.util.*; 2 3 public class ShellSort { 4 public int[] shellSort(int[] A, int n) { 5 int

希尔排序及希尔排序java代码

原文链接:http://www.orlion.ga/193/ 由上图可看到希尔排序先约定一个间隔(图中是4),然后对0.4.8这个三个位置的数据进行插入排序,然后向右移一位对位置1.5.9进行插入排序按照此规律直到全部参与了排序.然后将间隔约定为4-1=3,然后继续进行如上的排序方法.具体过程如下: 9 1 2 3 0 4 5 7 6 8 Setp 1 经过间隔为4排序后变成 : 0 1 2 3 6 4 5 7 9 8 Setp 2 经过间隔为3排序后变成 : 0 1 2 3 6 4 5 7 9

java排序之插入排序(直接插入排序和希尔排序)

上面一片博文探讨了关于的java选择排序(冒泡排序和快速排序)本章将继续探讨java排序之插入排序,插入排序分为直接插入排序和希尔排序两种. 1.直接插入排序思想:在需要排序的一组数据中假设前该数组的前n-1(n >= 2)个数是已经排好序的,现在要把第n个数插入到前面的n-1个数中,使得这n个数也是排好顺序的.如此反复进行,知道n等于需要排序的数组的长度时.就实现了该数组的直接插入排序. 代码如下: /** * * @param a 需要排序的数组 */ public static void

【算法拾遗(java描写叙述)】--- 插入排序(直接插入排序、希尔排序)

插入排序基本思想 每次将一个待排序的记录按其keyword大小插入到前面已经拍好序的子文件的适当位置,直到全部记录插入完毕为止. 直接插入排序 基本思想 直接插入排序的基本操作是将一个记录插入到已排好序的有序表中.从而得到一个新的有序表.即如果待排序的记录存放在数组R[1······n]中,排序过程中,R被分成两个子区间R[1······i]和R[i+1······n],当中.R[1······i]是已经排好序的有序区:R[i+1······n]是当前未排序的部分. 将当前无序区的第一个记录R[