–堆排序是指利用‘堆’这种数据结构进行排序,而堆则是完全二叉树的一种特殊情况,即在完全二叉树中,若每个根节点均大于(或小于)其孩子节点,则这个完全二叉树称为最大堆(最小堆)。 其算法思路如下:
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)
堆排序的复杂度较复杂,这里不作讨论,将在之后的排序总结里统一讨论。