1、堆的定义
满足以下情形的数据结构:
情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆:左、右子孩子的值比父结点的值都大)
情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆:左、右子孩子的值比父结点的值都小)
2、堆排序
一般从小到大的排序利用大顶堆实现。基本思想为:
1、将初始待排序关键字序列构建成大顶堆
2、将堆顶元素R[1]与最后一个元素R[n]交换,此时得到新的无序区(R1,R2,......Rn-1)和新的有序区(Rn),且满足R[1,2...n-1]<=R[n];
3、由于交换后新的堆顶R[1]可能违反堆的性质,而其他节点均满足堆的性质,因此只需要从堆顶开始对当前无序区(R1,R2,......Rn-1)调整为新堆,然后再次将R[1]与无序区最后一个元素交换,得到新的无序区(R1,R2....Rn-2)和新的有序区(Rn-1,Rn)。不断重复此过程直到有序区的元素个数为n-1,则整个排序过程完成。
3、堆的生成
叶节点不用调整,首先应该从最后一个非子节点开始,即序号N/2-1节点。
def heapAdjust(a,i,n): while i*2+1<n: j = i*2+1 if j+1<n: if a[j+1]>a[j]: j += 1 t = a[i] if a[j]>t: a[i] = a[j] a[j] = t i = j else: break从N/2-1节点向前调整,至此生成一个大顶堆。
i = length//2-1 a = tinput while i>=0: adjust(a,i,length) i-=14、堆排序
将堆顶和最后一个元素进行交换,然后对前面的元素进行调整。
t = a[0] a[0] = a[length-1] a[length-1] = t N = length-1 while N>0: heapAdjust(a,0,N) t = a[0] a[0] = a[N-1] a[N-1] = t N-=1完整代码:
def adjust(a,i,n): while i*2+1 < n: j = i*2+1 t = a[j] if j+1<n: if a[j]<a[j+1]: t = a[j+1] j = j+1 if a[i]<a[j]: a[j] = a[i] a[i] = t i = j else: break i = length//2-1 a = tinput while i>=0: adjust(a,i,length) i-=1 t = a[0] a[0] = a[length-1] a[length-1] = t N = length-1 while N>0: adjust(tinput,0,N) t = a[0] a[0] = a[N-1] a[N-1] = t N-=1