#堆排序 #可用 #1、建一个完全二叉树 #2、调整为一个初始堆,为大根堆,第一个值最大 #3、进行堆排序,调整为小根堆,最后一个值最大 #4、topK问题,剩余的n-k个数与已排好序的小根堆进行比较 #对数组来说,以下标index为根节点的左右子树的下标为 index * 2 + 1, index * 2 + 2 # 将length个元素,i为节点的数组堆化(i的子节点也都是堆) def big_heap_array(array, i, length): # 左叶子节点 temp_value = array[i] node_index = (i << 1) + 1 while node_index < length: # print("1==node_index={}".format(node_index)) #左右叶子节点的较大值 if node_index + 1 < length and array[node_index + 1] > array[node_index]: node_index = node_index + 1 # print("2==node_index={}".format(node_index)) # 如果根节点大于叶子节点,说明已经是堆,退出循环。 if array[node_index] < temp_value: # print("array={}".format(array)) break array[i] = array[node_index] #交换i与node_index的下标的值 # 调整交换过元素的子节点 i = node_index # print("i={}".format(i)) node_index = (i << 1) + 1 # print("3==node_index={}".format(node_index)) # print("array[i]={}".format(array[i])) array[i] = temp_value #最后一个值与根节点调换 #建一个完全二叉树,即一个无序数组 #2、调整为一个初始堆,为大根堆,第一个值最大 def build_heap(array, length): #从最后一个非叶子节点开始比较 last_parent = length >>1 #最后一个根结节点下标[size/2-1] for last_parent in range(last_parent,-1,-1): big_heap_array(array, last_parent, length) # 堆顶最大值和最后一个数互换, 然后对大根堆进行排序,从小到大排序, # 最大一个值为最大值,为一个小根堆 for index in range(length - 1, 0, -1): array[0], array[index] = array[index], array[0] big_heap_array(array, 0, index) if __name__ == "__main__": #大顶堆排序 lst = [2,3,6,1,9,5,8,10,21,20,80,76,33,99,100] lst1 = [] lst1 = lst[0:10] print('source lst1:',lst1) build_heap(lst1, len(lst1)) print("sort lst1:", lst1) #lst [1, 2, 3, 5, 6, 8, 9, 10],结果为这个 #遍历剩余的n-k个数据,寻找最大的topk个 # for index in range(len(lst1), len(lst)): # #与堆顶元素比较 # comptemp = lst[index] # if comptemp > lst1[0]: # #如果大于堆顶值,进行交换,然后对堆进行排序 # lst1[0] = comptemp # build_heap(lst1,len(lst1)) # else: # continue # print('source lst: ',lst ) # print("sort topK lst", lst1) #遍历剩余的n-k个数据,寻找最小的的topK个 for index in range(len(lst1), len(lst)): #与堆顶元素比较 comptemp = lst[index] if comptemp < lst1[0]: #如果大于堆顶值,进行交换,然后对堆进行排序 lst1[0] = comptemp build_heap(lst1,len(lst1)) else: continue print('source lst: ',lst ) print("sort topK lst", lst1) #程序证明是正确的