希尔排序python 简书_数据结构-希尔排序

前言

希尔排序,又称“缩小增量排序”,也是插入排序的一种,是插入排序的一种更高效的改进版本

原理

在使用直接插入排序算法时,如果表中的记录只有个别的是无序的,多数保持有序,这种情况下算法的效率也会比较高;除此之外,如果需要排序的记录总量很少,该算法的效率同样会很高。希尔排序就是从这两点出发对算法进行改进得到的排序算法。

希尔排序的具体实现思路是:先将整个记录表分割成若干部分,分别进行直接插入排序,然后再对整个记录表进行一次直接插入排序。

算法步骤

选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;

按增量序列个数 k,对序列进行 k 趟排序;

每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

算法演示

排序动画过程解释

首先,选择增量 gap = 10/2 ,缩小增量继续以 gap = gap/2 的方式

初始增量为 gap = 10/2 = 5,整个数组分成了 5 组

按颜色划分为【 8 , 3 】,【 9 , 5 】,【 1 , 4 】,【 7 , 6 】,【 2 , 0 】

对这分开的 5 组分别使用

上节所讲的插入排序

结果可以发现,这五组中的相对小元素都被调到前面了

缩小增量 gap = 5/2 = 2,整个数组分成了 2 组

【 3 , 1 , 0 , 9 , 7 】,【 5 , 6 , 8 , 4 , 2 】

对这分开的 2 组分别使用上节所讲的插入排序

此时整个数组的有序性是很明显的

再缩小增量 gap = 2/2 = 1,整个数组分成了 1 组

【 0, 2 , 1 , 4 , 3 , 5 , 7 , 6 , 9 , 0 】

此时,只需要对以上数列进行简单的微调,不需要大量的移动操作即可完成整个数组的排序

代码实现

C++代码

排序数据 演示

//gap = gap/2

// 0 1 2 3 4 5 6 7 8 9 数据下标

// 49 33 65 97 76 13 27 49 55 04 排序数据

// 步长 == 数组长度/2 == 5 然后插入排序算法

//首先按照步长去分组

// 49 13

// 33 27

// 65 49

// 97 55

// 76 04

//然后对每组进行排序

// 13 49

// 27 33

// 49 65

// 55 97

// 04 76

//当前数组变为

// 13 27 49 55 04 49 33 65 97 76

// 步长 == 上次步长/2 == 2

//按照步长去分组

// 13 49 04 33 97

// 27 55 49 65 76

//然后对每组进行插入排序

// 04 13 33 49 97

// 27 49 55 65 76

// 当前数组变为

// 04 27 13 49 33 55 49 65 97 76

//步长 == 上次步长/2 == 1

//然后对数组进行插入排序

// 04 13 27 33 49 49 55 65 76 97

//

代码

#pragma mark --希尔排序 交换

void shellExchangeInsertion_sort(int array[], int last) {

int times = 0;

int addGap =2;

//分组 直到为1时 分组结束

for (int gap = last/addGap; gap >= 1; gap = gap/addGap) {

if (gap < addGap){

gap = 1;

}

//对分组的数据进行插入排序

for (int i = gap; i < last; i++) {

for (int j = i - gap; j >= 0 && array[j] > array[j + gap]; j = j - gap) {

int temp = array[j];

array[j] = array[j + gap];

array[j+ gap] = temp;

times ++;

}

}

}

}

void shellInsertion_sort(int array[], int last) {

int times = 0;

//分组 直到为1时 分组结束

for (int gap = last/2; gap >= 1; gap = gap/2) {

//对分组的数据进行插入排序

for (int i = gap; i < last; i++) {

int temp = array[i];

int j = i - gap;

for (; j >= 0 && array[j] > temp; j = j - gap) {

array[j + gap] = array[j];

times ++;

}

array[j+ gap] = temp;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值