经典算法 之 折半插入排序 python实现

活动地址:CSDN21天学习挑战赛


1.排序算法

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减排列起来的操作。排序是计算机内经常进行的一种操作,其目的是将一组无序的记录序列调整为有序的记录序列。


评价指标

  • 时间复杂度
  • 空间复杂度
  • 使用场景:针对实际对节省时间和空间的不同需求,选择适用于不同场景的排序算法
  • 稳定性:稳定的算法在排序过程中不会改变元素彼此之间次序

不同排序算法O(n)分类

排序算法平均时间复杂度度
冒泡排序 O ( n 2 ) O(n^2) O(n2)
选择排序 O ( n 2 ) O(n^2) O(n2)
插入排序 O ( n 2 ) O(n^2) O(n2)
希尔排序 O ( n 3 / 2 ) O(n^{3/2}) O(n3/2)
快速排序 O ( n ∗ log ⁡ n ) O(n*\log n) O(nlogn)
归并排序 O ( n ∗ log ⁡ n ) O(n*\log n) O(nlogn)
堆排序 O ( n ∗ log ⁡ n ) O(n*\log n) O(nlogn)
基数排序 O ( d ( n + r ) ) O(d(n+r)) O(d(n+r))

2. 插入排序

插入排序适用于少量数据且基本有序的排列。
插入排序将排序数组分为两部分:第一部分为除最后一个元素的所有元素组成的数组,第二部分为最后一个元素(待插入元素)。第一部分完成排序后,将第二部分插入第一部分。


折半插入排序

折半插入排序(Binary Insertion Sort)是对插入排序算法的一种改进,所谓排序算法过程,就是不断的依次将元素插入前面已排好序的序列中。

排序思想

有一组数据待排序,排序区间为Array[0]~Array[n-1]。将数据分为有序数据和无序数据,第一次排序时默认Array[0]为有序数据,Array[1]~Array[n-1]为无序数据。有序数据分区的第一个元素位置为low,最后一个元素的位置为high

遍历无序区间的所有元素,每次取无序区间的第一个元素Array[i],因为0~i-1是有序排列的,所以用中点m将其平分为两部分,然后将待排序数据同中间位置为m的数据进行比较,若待排序数据较大,则low~m-1分区的数据都比待排序数据小,反之,若待排序数据较小,则m+1~high分区的数据都比 待排序数据大,此时将lowhigh重新定义为新的合适分区的边界,对新的小分区重复上面操作。直到lowhigh 的前后顺序改变,此时high+1所处位置为待排序数据的合适位置。

算法评价

  • 时间复杂度:O(n^2)
  • 稳定性:稳定

3. 算法实践(Python)

折半插入排序

参考代码折半插入排序的 python 实现

#--coding: utf8 --
def bin_insertion_sort(arr):
	arrlen = len(arr)
	for i in range(1, arrlen):
		insert(arr, i)
		
def insert(arr, i):
	bin_insert(arr, 0, i - 1, i)
	
		
def bin_insert(arr, low, high, i):
	# low > high是这个递归的终止条件
	middle = (low + high) // 2
	if low <= high:
		if arr[middle] < arr[i]:
			# i应该在的位置在middle后面
			bin_insert(arr, middle + 1, high, i)
		else:
			# i应该在的位置在middle前面
			bin_insert(arr, low, middle - 1, i)
	else:
		tmp = arr[i]

		for j in reversed(range(low, i)):
			arr[j + 1] = arr[j]
		
		arr[low] = tmp

		
arr = [3,9,8,4,5,2,10,18,4]
bin_insertion_sort(arr)
print(arr)
[2, 3, 4, 4, 5, 8, 9, 10, 18]

参考

1.一文学懂经典算法系列之:直接插入排序
2.张清云.《Python数据结构学习笔记》(ISBN:9787113269999)
3. 排序----折半插入排序
4.折半插入排序的 python 实现


@夏日回

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值