一、概述
1、希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序
2、基本思想:先将整个待排序的记录序列按照一定的间隔直接插入排序,然后按照一定的规则间隔逐渐缩小,直到缩小为1,这样循环的去插入排序。
3、算法流程:
1)选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
2)按增量序列个数k,对序列进行k 趟排序;
3)每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
4、时间复杂度:O(n^(1+e))(其中0<e<1),在元素基本有序的情况下,效率很高。希尔排序是一种不稳定的排序算法。
5、希尔排序的示例:
一、希尔排序实现代码如下:
package com.tool.wpn.quicksort;
import android.util.Log;
/**
* Created by Xi on 2017/8/13.
* 希尔排序
*/
public class ArrayShell {
private long[] theArray;
private int nElems;
public ArrayShell(int max){
theArray=new long[max];
nElems=0;
}
public void insert(long value){
theArray[nElems]=value;
nElems++;
}
public void display(){
StringBuilder sb=new StringBuilder();
sb.append("[");
for(int i=0;i<nElems;i++){
if(i==nElems-1)
sb.append(theArray[i]);
else {
sb.append(theArray[i]);
sb.append(",");
}
}
sb.append("]");
Log.v("ArrayShell",sb.toString());
}
/**
* 希尔排序
*/
public void shellSort(){
int inner,outer;
long temp;
int h=1;//俩数比较的间隔,插入排序是1,从头比较到尾,而希尔排序不是,是从大间隔到小间隔变化
while(h<=nElems/3)//计算最大间隔,如果100个数据,则n=40
h=h*3+1;//1 4 13 40
while(h>0){//循环间隔进行间隔有序排序,依次按40、13、4、1间隔来进行插入排序
for(outer=h;outer<nElems;outer++){//进行间隔排序,每次进行左右各一个数进行交换,他们的间隔是h
temp=theArray[outer];
inner=outer;
while(inner>h-1 && theArray[inner-h]>=temp){//如果左边数大于右边数进行交换
theArray[inner]=theArray[inner-h];
inner-=h;
}
theArray[inner]=temp;//如果左边数不大于右边数就不用交换
}
h=(h-1)/3;//调整间隔
}
}
}
二、主函数调用如下:
/**
* 希尔排序
* 是在插入排序的基础上的升级。是带有间隔的插入排序。
* 首先按照
*/
private void sortShell(){
int maxSize=20;
ArrayShell array=new ArrayShell(maxSize);
for(int i=0;i<maxSize;i++){//随机赋值
long num=(int)(Math.random()*99);
array.insert(num);
}
array.display();
array.shellSort();//调用希尔排序
array.display();
}
日志打印如下:
08-15 10:37:48.913 25472-25472/com.tool.wpn.quicksort V/ArrayShell: [0,70,66,23,42,19,82,95,81,24,34,65,10,42,35,12,20,98,38,50]
08-15 10:37:48.913 25472-25472/com.tool.wpn.quicksort V/ArrayShell: [0,10,12,19,20,23,24,34,35,38,42,42,50,65,66,70,81,82,95,98]
源码下载地址:点击打开链接