希尔排序 - python

希尔排序是一种分组插入排序算法,通过逐步缩小元素间的间隔进行排序。文章介绍了希尔排序的工作原理,包括分组、直接插入排序和逐步缩小间隔的过程,并提供了一个Python代码示例。

希尔排序

希尔排序时一种分组插入排序算法。

首先取一个整数d1=n/2,将元素分为d1个组,每组相邻元素之间距离为d,在各组内进行直接插入排序;
取第二个整数d2=d1/2,重复上述分组排序过程,直到di=1,即所有元素在同一组内进行直接插入排序。

希尔排序每趟并不使某些元素有序,而是使整体数据越来越接近有序,最后一趟排序使得所有数据有序。

例:取整数d = 9//2 = 4
在这里插入图片描述
将元素分为4组
在这里插入图片描述
组内进行直接插入排序
在这里插入图片描述
归位
在这里插入图片描述
取d = 4/2 = 2,分为两组,进行组内排序
在这里插入图片描述
d=2归位后,再取d=2/2=1,直接插入排序即可完成排序。
在这里插入图片描述
希尔排序

希尔排序是一种分组插入排序算法,其基本思想是通过缩小增量和分组插入排序的方式,减少逆序对的数量,提高排序效率。以下结合引用中的代码,详细解释希尔排序Python 实现。 ### 代码示例 1 ```python def shell_sort(array): interval = int(len(array)/3) while interval > 0: for i in range(interval, len(array)): cur_index = i - interval while cur_index >= 0 and array[cur_index] > array[cur_index+interval]: array[cur_index+interval], array[cur_index] = array[cur_index], array[cur_index+interval] cur_index -= interval interval = int(interval/3) return array if __name__ == '__main__': array = [10, 17, 50, 7, 30, 24, 27, 45, 15, 5, 36, 21] print(shell_sort(array)) ``` #### 代码解释 1. **初始化间隔**:`interval = int(len(array)/3)` 这行代码计算初始的间隔,该间隔用于分组。例如,对于长度为 12 的数组,初始间隔为 4。 2. **外层循环**:`while interval > 0` 确保间隔大于 0 时持续进行分组排序。每次循环结束后,间隔缩小为原来的 1/3,即 `interval = int(interval/3)`。 3. **中层循环**:`for i in range(interval, len(array))` 用于遍历每一组的元素。从间隔位置开始,处理每一个元素。 4. **内层循环**:`while cur_index >= 0 and array[cur_index] > array[cur_index+interval]` 对每组元素进行插入排序。如果当前元素大于间隔后的元素,则交换它们的位置,并将索引减间隔,继续比较。 ### 代码示例 2 ```python def shell_sort(arr): n = len(arr) gap = n // 2 # 初始增量 # 开始希尔排序 while gap > 0: # 做一次插入排序,增量为gap for i in range(gap, n): temp = arr[i] j = i # 将temp插入到它应该在的位置 while j >= gap and arr[j - gap] > temp: arr[j] = arr[j - gap] j -= gap arr[j] = temp # 减小增量 gap //= 2 # 示例 arr = [9, 8, 3, 7, 5, 6, 4, 1] shell_sort(arr) print("Sorted array is:", arr) ``` #### 代码解释 1. **初始化增量**:`gap = n // 2` 计算初始增量,将数组分成若干组。 2. **外层循环**:`while gap > 0` 控制增量不断缩小,直到增量为 1。每次循环结束后,增量缩小为原来的一半,即 `gap //= 2`。 3. **中层循环**:`for i in range(gap, n)` 遍历每一组的元素,从增量位置开始。 4. **内层循环**:`while j >= gap and arr[j - gap] > temp` 对每组元素进行插入排序。如果当前元素大于前面间隔位置的元素,则将前面的元素后移,直到找到合适的位置插入当前元素。 ### 代码示例 3 ```python nums = [5,3,6,4,1,2,8,7] def ShellSort(nums): step = len(nums)//2 # 初始化增量为数组长度的一半 while step > 0: for i in range(step, len(nums)): ind = i while ind >= step and nums[ind] < nums[ind-step]: nums[ind], nums[ind-step] = nums[ind-step], nums[ind] ind -= step step //= 2 print(nums) ShellSort(nums) ``` #### 代码解释 1. **初始化步长**:`step = len(nums)//2` 初始化步长为数组长度的一半,确定初始分组。 2. **外层循环**:`while step > 0` 确保步长大于 0 时持续进行分组排序。每次循环结束后,步长缩小为原来的一半,即 `step //= 2`。 3. **中层循环**:`for i in range(step, len(nums))` 遍历每一组的元素,从步长位置开始。 4. **内层循环**:`while ind >= step and nums[ind] < nums[ind-step]` 对每组元素进行插入排序。如果当前元素小于前面步长位置的元素,则交换它们的位置,并将索引减步长,继续比较。 ### 总结 希尔排序通过多次分组插入排序,逐步缩小间隔,最终使数组有序。初始时,大间隔分组可以快速将元素大致排序;随着间隔缩小,数组逐渐接近有序,最后一次间隔为 1 的排序即普通的插入排序,此时数组已经基本有序,插入排序效率较高。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值