堆排序

__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:]))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值