我终于把堆排序写出来了!!!
有个总结:当你觉得一个东西很难的时候,胡乱的看博客可能是极其浪费时间的,你就是打开一篇博客,然后another;如果可以的话可以找个视频看看,然后看看对应的书,沉下心慢慢看,慢慢思考,逐渐脱离书本写程序。
涉及知识点:
- 堆排序首先要建立堆
- 大顶堆(父节点>=左右子节点),小顶堆(父节点<=左右子节点)
- 在列表中实现二叉树,若父节点为alist[i],其左右子节点肯定是alist[2*i+1],alist[2*i+2]
- 建堆的过程是找到最后一个父节点,向左一个个建堆,所以有for i in range(end // 2, -1, -1)
- 堆排序(假设是小堆,排序后为递减):每次把堆顶的节点取出,放到堆底,然后把堆底的数放到堆顶,向下筛选,构建了一个新的堆(新堆的长度每次都减一)
alist=[1,3,12,34,12,1,3,2,4]
'''小顶堆,排序后是降序'''
def siftdown(alist, e, begin, end):
i, j = begin, begin * 2 + 1
while j < end:
if j + 1 < end and alist[j + 1] < alist[j]:
j += 1
if e < alist[j]:
break
alist[i] = alist[j]
i, j = j, 2 * j + 1
alist[i] = e
def build_heat(alist):
''构建小顶堆,从最后一个父节点开始''''
end = len(alist)
for i in range(end // 2, -1, -1):
siftdown(alist, alist[i], i, end)
def heat_sort(alist):
'''堆排序,排序n-1次,向下筛选的过程'''
end=len(alist)
for i in range(end-1,0,-1):
e=alist[i]
alist[i]=alist[0]
siftdown(alist,e,0,i)
def enqueue(alist,e):
'''在堆中插入元素,这是一种向上筛选的过程'''
alist.append(None)
end=len(alist)-1
i,j=end,(end-1)//2
while i>0 and e<alist[j]:
alist[i]=alist[j]
i,j=j,(j-1)//2
alist[i]=e
build_heat(alist)
print(alist)
#[1, 2, 1, 3, 12, 12, 3, 34, 4]
enqueue(alist,18)
print(alist)
[1, 2, 1, 3, 12, 12, 3, 34, 4, 18]
heat_sort(alist)
print(alist)
[34, 18, 12, 12, 4, 3, 3, 2, 1, 1]