算法基础之----希尔排序

插入排序的改良----希尔排序(ShellSort)

基本介绍:

         希尔排序是直接插入排序的改良算法,所以,时间复杂度肯定优于直接插入排序。其主要思路还是直接插入排序的思想,与之不同的就是,希尔排序将一个待排序的序列进行了分组操作,对每一组分别进行直接插入排序。

算法思想:(假设数组arr的长度为n)

         先取一个小于n的整数d1(n/2)作为第一个增量,把数组的全部元素进行分组。所有距离为d1的倍数的元素放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2(d1/2)<d1重复上述的分组和排序,直至所取的增量dt=1( dt <d(t-1)<…<d2<d1),此时,所有的元素放在同一组中进行直接插入排序为止。这就完成了希尔排序的整个过程。

如图所示:

手工过程:

假设某组数据有37个元素,count = 37;
           第一轮步长为:18(count/2),需要从下标为0开始到下标17,每一组都进行一次直接插入排序;
           若中间某步的步长为s,则下标为0,到下标s-1,且每组进行直接插入排序;
           重复此过程,每次步长为前一次步长的1/2(第一次步长为count/2),直到步长为0的时候结束循环。

伪代码: C语言:

#include<stdio.h>
#include<malloc.h>
#include<time.h>
#include<stdlib.h>

typedef unsigned char boolean;

#define TRUE		1
#define FALSE		0

void initData(int *array, int count, int minValue, int maxValue);
void showArray(int *array, int count);
void insertSort(int *array, int count, int startIndex, int step);
void shellSort(int *array, int count);

void shellSort(int *array, int count) {
	int step;
	int startIndex;

	for(step = count/2; step > 0; step/=2) {
		for(startIndex = 0; startIndex < step; startIndex++) {
			insertSort(array, count, startIndex, step);
		}
	}
}

void insertSort(int *array, int count, int startIndex, int step) {
	int i;
	int j;
	int tmp = 0;

	for(i = startIndex+step; i < count; i+=step) {
		int index;
		tmp = array[i];
		for(index = startIndex; index < i && tmp > array[index]; index+=step);
		
		for(j = i; j > index; j-=step) {
			array[j] = array[j-step];
		}

		array[index] = tmp;
	}
}

void showArray(int *array, int count) {
	int i;

	for(i = 0; i < count; i++) {
		printf(i == 0 ? "%d" : ", %d", array[i]);
	}
	printf("\n");
}

void initData(int *array, int count, int minValue, int maxValue) {
	int i = 0;
	int value = maxValue - minValue + 1;

	srand(time(0));
	for(i = 0; i < count; i++) {
		array[i] = minValue + rand()%value;
	}
}

void main(void) {
	int *array;

	array = (int *)calloc(sizeof(int), 20);
	initData(array, 20, 1, 100);
	showArray(array, 20);
	
	shellSort(array, 20);

	showArray(array, 20);
}
Java语言:

public class ShellSort {
	public static void main(String[] args) {
		int[] array = new int[20];
		initData(array, 200);
		showData(array);
		
		shellSort(array);
		
		showData(array);
	}
	
	private static void shellSort(int[] array) {
		if(array == null) {
			throw new RuntimeException("array is null!");
		}
		
		int len = array.length;
		if(len == 0) {
			throw new RuntimeException("array length is zero!");
		}
		
		for(int step = len/2; step > 0; step/=2) {
			for(int startIndex = 0; startIndex < step; startIndex++) {
				insertSort(array, len, startIndex, step);
			}
		}
	}

	private static void insertSort(int[] array, int len, int startIndex, int step) {
		int tmp = 0;
		
		for(int i = startIndex+step; i < len; i+=step) {
			tmp = array[i];
			int index = 0;
			for(index = startIndex; index < i && array[index] < tmp; index+=step);
			
			for(int j = i; j > index; j-=step) {
				array[j] = array[j-step];
			}
			array[index] = tmp;
		}
	}


	/**
	 * 显示数组
	 * @param array
	 */
	private static void showData(int[] array) {
		for(int i = 0; i < array.length; i++) {
			System.out.printf(i == 0 ? "%d" : ", %d", array[i]);
		}
		System.out.println();
	}

	/**
	 * 初始化一个数组,元素随机产生
	 * @param array		要初始化的数组
	 * @param maxValue	数组元素的最大值
	 */
	private static void initData(int[] array, int maxValue) {
		for(int i = 0; i < array.length; i++) {
			array[i] = (int)(Math.random()*maxValue);
		}
	}
}

讨论:

1)、时间和空间复杂度的分析:
          时间复杂度:平均:O(NlogN),极端情况:O(n^2)
          空间复杂度:O(1)

2)、非稳定排序


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值