【排序算法】7.堆排序

–堆排序是指利用‘堆’这种数据结构进行排序,而堆则是完全二叉树的一种特殊情况,即在完全二叉树中,若每个根节点均大于(或小于)其孩子节点,则这个完全二叉树称为最大堆(最小堆)。 其算法思路如下:
1.先将一个数组堆积成最大堆,此时根节点的值即为最大值。
2.交换跟节点和末节点,并除去末节点。
3.对数组的1~n-1位再次排列成最大堆,即不断重复1、2步骤,直至完全排列完。
python代码如下:

# coding:gbk
def bigheadheap(nums):
	'''
	将数组调整成最大堆
	'''
	for start in range(len(nums)//2-1, -1,-1):
		root = start
		# 从最后一个根节点开始,从右往左,从下往上排堆
		child = root*2 +1
		while child < len(nums):
			# 判断左孩子和右孩子大小,将指针指向大的那个数
			if child+1 < len(nums) and nums[child] < nums[child+1]:
				child += 1
			# 判断父节点和子节点,若子节点大则交换
			if nums[root] < nums[child]:
				nums[root], nums[child] = nums[child], nums[root]
				root = child
			else:
			    #如果父节点大于子节点则直接退出循环
				#print('a',nums)
				break 
			#每次交换完都从上往下检查其子节点是否符合最大堆结构
			child = root*2 +1
			#print(nums)

def heap_sort(nums):
	k = len(nums)
	for i in range(k-1, -1, -1):
		#从最后一个数开始往前排,每次输入的数组长度减一,
		bigheadheap(nums[0:i+1])
		#print('b',nums)
		#交换第一个数即根节点和最后一个叶子节点
		nums[0],nums[i] = nums[i],nums[0]
		#print(nums)
nums = [56, 5, 3, 66, 4, 1]

heap_sort(nums)
print('ans' , nums)

这个代码里面有个问题,下面这段代码如果使用切片形式输入参数nums[0:i+1],那么相当于形成了一个新的数组,分配了新的数组空间,在bigheadheap函数里面的nums与heap_sort里面的nums并不是同一个数组。

   		bigheadheap(nums[0:i+1])

因此要修改代码,将整个数组当参数传入函数,同时传入参数end代表数组终点。修改代码如下:

# coding:gbk
def bigheadheap(nums,end):
	'''
	将数组调整成最大堆
	'''
	for start in range((end+1)//2-1, -1,-1):
		root = start
		child = root*2 +1
		while child <= end:
			if child+1 <= end and nums[child] < nums[child+1]:
				child += 1
			if nums[root] < nums[child]:
				nums[root], nums[child] = nums[child], nums[root]
				root = child
			else:
				break 
			child = root*2 +1

def heap_sort(nums):
	end = len(nums)-1
	for i in range(end, -1, -1):
		bigheadheap(nums,i)
		nums[0],nums[i] = nums[i],nums[0]

nums = [56, 5, 3, 66, 4, 1,56457,3,11]
heap_sort(nums)
print('ans' , nums)

堆排序的复杂度较复杂,这里不作讨论,将在之后的排序总结里统一讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值