希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是把记录按下标的必定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减小,每组包含的记录愈来愈多,当增量减至1时,整个文件恰被分红一组,算法便终止。 python
在前面文章中介绍的直接插入排序,它对于已经基本有序的数据进行排序,效率会很高,而若是对于最初的数据是倒序排列的,则每次比较都须要移动数据,致使算法效率下降。算法
希尔排序的基本思想就是:将须要排序的序列逻辑上划分为若干个较小的序列(但并不是真的分割成若干分区),对这些逻辑上序列进行直接插入排序,经过这样的操做可以使须要排序的数列基本有序,最后再使用一次直接插入排序。shell
在希尔排序中首先要解决的是怎样划分序列,对于子序列的构成不是简单地分段,而是采起将相隔某个增量的数据组成一个序列。通常选择增量的规则是:取上一个增量的一半做为这次子序列划分的增量,通常初始值元素的总数量的一半。数组
# 建立一个希尔排序的函数 def shell_sort(alist): # 须要排序数组的个数 N = len(alist) # 最初选取的步长 gap = N//2 # 根据每次不一样的步长,对分组内的数据进行排序 # 若是步长没有减为1就继续执行 while gap>0: # 对每一个分组进行插入排序, # 由于插入排序从第二个元素开始,而这里第二个元素的下标就是gap # 因此i的起始点是gap for i in range(gap,N): # 控制每一个分组内相邻的两个元素,逻辑上相邻的两个元素间距为gap, # j的前一个元素比它少一个gap距离,因此for循环中j的步长为 -gap for j in range(i,0,-gap): # 判断和逻辑上的分组相邻的两个数据大小 if alist[j]<alist[j-gap] and j-gap>=0: # 交换 temp = alist[j] alist[j] = alist[j-gap] alist[j-gap] = temp # 改变步长 gap = gap//2 numlist = [5,7,8,3,1,2,4,6,9] print("排序前:%s"%numlist) shell_sort(numlist) print("排序后:%s"%numlist)
运行结果为:函数
排序前:[5, 7, 8, 3, 1, 2, 4, 6, 9]
排序后:[1, 2, 3, 4, 5, 6, 7, 8, 9]
#include <stdio.h> // 建立一个希尔排序的函数 void shell_sort(int arr[],int arrLength,int gap) { // 根据每次不一样的步长,对分组内的数据进行排序 // 若是步长没有减为1就继续执行 while (gap>0) { // 对每一个分组进行插入排序, // 由于插入排序从第二个元素开始,而这里第二个元素的下标就是gap, // 因此i的起始点是gap for (int i = gap; i<arrLength; i++) { // 控制每一个分组内相邻的两个元素,逻辑上相邻的两个元素间距为gap, // j的前一个元素比它少一个gap距离,因此for循环中j每次减小一个gap // 由于j-gap是上一个元素的下标,也必须保证大于等于0 for (int j = i; j>0&&j-gap>=0; j=j-gap) { // 判断和逻辑上的分组相邻的两个数据大小 if (arr[j]<arr[j-gap]) { // 交换 int temp = arr[j]; arr[j] = arr[j-gap]; arr[j-gap] = temp; } } } gap = gap/2; } } int main(int argc, const char * argv[]) { // 定义数组 int array[] = {5,7,8,3,1,2,4,6,9}; // 希尔排序的声明 void shell_sort(int arr[],int arrLength,int gap); // 计算数组长度 int len = sizeof(array)/sizeof(int); // 制定gap为二分之一的长度 int g = len/2; // 使用希尔排序 shell_sort(array, len, g); // 验证 for (int i = 0; i<len; i++) { printf("%d ",array[i]); } return 0; }
运行结果为:spa
1 2 3 4 5 6 7 8 9
因为屡次插入排序,咱们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不一样的插入排序过程当中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,因此shell排序是不稳定的。3d