__author__ = 'zhouhai'
import math
def build_heap(list_old):
#给待排序的数组的第0位,多弄了一个0,方便计算用;实际上有效的数组是:list[1:]
list = [0]
for number in list_old:
list.append(number)
#如果待排序的数值只有1个,就是加上前面的无效数值0,长度小于等于2
if len(list) <= 2 :
return list
#建一个大根堆;
for j in range(0,int(math.log2(len(list)))):
for i in range(1,int(len(list)/2)+1):
if 2*i < len(list) and list[i] < list[2*i]:
temp = list[2*i]
list[2*i] = list[i]
list[i] = temp
if 2*i+1 < len(list) and list[i] < list[2*i+1]:
temp = list[2*i+1]
list[2*i+1] = list[i]
list[i] = temp
return list
#开始进行堆排序
def start_to_sort(list):
sorted_number = 0
#每次把根元素和最后一个未排序的元素进行置换,一旦置换了,那么那个位置就属于排序状态;根元素需要跟左右元素进行调整,重新调整为大根堆
for i in range(len(list)-1,1,-1):
temp = list[i]
list[i] = list[1]
list[1] = temp
#置换一次,sort_number加1,说明又成功排序了一位数字
sorted_number += 1
#while循环,是一个重新调整为大根堆的过程
j = 1
while True:
#当左节点不存在,就不需要再调整堆啦
if 2*j > len(list)-1-sorted_number:
break
#当右节点不存在,就只判断是否需要跟左节点置换
elif 2*j+1 > len(list)-1-sorted_number:
if list[j] < list [2*j]:
temp = list[2*j]
list[2*j] = list[j]
list[j] = temp
break
#当根比左右节点都大的时候,就不需要再调整了
if list[j] >= list[2*j] and list[j] >= list[2*j+1]:
break
#如果根节点跟左右节点比较,不是最大的;找出左右节点中较大的节点,然后与根节点进行置换
elif list[2*j] >= list[2*j+1]:
temp = list[2*j]
list[2*j] = list[j]
list[j] = temp
#如果置换的是左节点,下次是针对左边的堆进行调整,变成大根堆 j = j+1
j = 2*j
else:
temp = list[2*j+1]
list[2*j+1] = list[j]
list[j] = temp
#如果置换的是右节点,下次是针对右边的堆进行调整,变成大根堆 j = j+2
j = 2*j+1
if __name__ == '__main__':
list_old = [11,1,18,15,14,19,12,13,17,16,20,5,2,6,3,8,4,7,10,9,22,21,23,25,26,27,28,24,30,29]
list = build_heap(list_old)
print(" 建好的堆:"+str(list[1:]))
start_to_sort(list)
print("堆排序之后:"+str(list[1:]))
import math
def build_heap(list_old):
#给待排序的数组的第0位,多弄了一个0,方便计算用;实际上有效的数组是:list[1:]
list = [0]
for number in list_old:
list.append(number)
#如果待排序的数值只有1个,就是加上前面的无效数值0,长度小于等于2
if len(list) <= 2 :
return list
#建一个大根堆;
for j in range(0,int(math.log2(len(list)))):
for i in range(1,int(len(list)/2)+1):
if 2*i < len(list) and list[i] < list[2*i]:
temp = list[2*i]
list[2*i] = list[i]
list[i] = temp
if 2*i+1 < len(list) and list[i] < list[2*i+1]:
temp = list[2*i+1]
list[2*i+1] = list[i]
list[i] = temp
return list
#开始进行堆排序
def start_to_sort(list):
sorted_number = 0
#每次把根元素和最后一个未排序的元素进行置换,一旦置换了,那么那个位置就属于排序状态;根元素需要跟左右元素进行调整,重新调整为大根堆
for i in range(len(list)-1,1,-1):
temp = list[i]
list[i] = list[1]
list[1] = temp
#置换一次,sort_number加1,说明又成功排序了一位数字
sorted_number += 1
#while循环,是一个重新调整为大根堆的过程
j = 1
while True:
#当左节点不存在,就不需要再调整堆啦
if 2*j > len(list)-1-sorted_number:
break
#当右节点不存在,就只判断是否需要跟左节点置换
elif 2*j+1 > len(list)-1-sorted_number:
if list[j] < list [2*j]:
temp = list[2*j]
list[2*j] = list[j]
list[j] = temp
break
#当根比左右节点都大的时候,就不需要再调整了
if list[j] >= list[2*j] and list[j] >= list[2*j+1]:
break
#如果根节点跟左右节点比较,不是最大的;找出左右节点中较大的节点,然后与根节点进行置换
elif list[2*j] >= list[2*j+1]:
temp = list[2*j]
list[2*j] = list[j]
list[j] = temp
#如果置换的是左节点,下次是针对左边的堆进行调整,变成大根堆 j = j+1
j = 2*j
else:
temp = list[2*j+1]
list[2*j+1] = list[j]
list[j] = temp
#如果置换的是右节点,下次是针对右边的堆进行调整,变成大根堆 j = j+2
j = 2*j+1
if __name__ == '__main__':
list_old = [11,1,18,15,14,19,12,13,17,16,20,5,2,6,3,8,4,7,10,9,22,21,23,25,26,27,28,24,30,29]
list = build_heap(list_old)
print(" 建好的堆:"+str(list[1:]))
start_to_sort(list)
print("堆排序之后:"+str(list[1:]))