Python实现堆排序

Python实现堆排序

  1. 版本1
'''
# 简单思想
1、建立一个大根堆或者是小根堆    父节点的data域大于孩子节点的data域
2、取出堆顶后,将堆最后一个叶节点放在堆顶,同时调节堆
3、不断重复第二步,直到所有的元素被取出

如何循环判断调整 
完全二叉树可利用数组存储 依次存入
父节点和孩子节点的位置关系  i   i*2 i*2+1
'''
# !如果不传入length参数,会导致处理有序序列代价昂贵
# !关于最长length,申请空间是n+1 但去除标兵位置,length = n
# 堆排序
from numpy import random
def heapSort(nums):
    nums_length = len(nums) - 1 
    while(nums_length):
        swap(nums,nums_length)
        nums_length = nums_length - 1
        reHeap(nums,1,nums_length)
    return nums

# 调整大根堆  # *假设只有首节点没有融入堆中
def reHeap(nums,low,length): 
    # 建立哨兵  能不能建立哨兵? 是否每次传入都是从堆顶开始
    nums[0] = nums[low]
    j = 0
    # 未有哨兵版 temp = nums[i]
    # ! i是允许取到=的,比如元素只有一个的话
    while(low <= length and (j < length)):
        j = low*2
        # 如果左孩子大于右孩子  # !应该注意孩子节点不能超过数组下标
        if (j < length) and (nums[j + 1] > nums[j]) :
            j  = j + 1
        # 如果孩子节点大于父节点,元素赋值
        if (j < length) and (nums[j] > nums[0]):
            # 孩子节点上移
            nums[low] = nums[j]
            # 下标互换  # !为什么是下标互换,而不是平移?兄弟节点不看吗?
            # TODO 尽管满足大顶堆要求
            low = j  
        # 如果父节点最大,直接结束循环
        if (j < length) and  (nums[j] < nums[0]):
            break
    # 将相对父节点下标赋值元素
    nums[low] = nums[0]
    return nums

# 交换堆顶和堆尾元素
def swap(nums,length):
    nums[1] , nums[length] =  nums[length],nums[1] 
    # 由于传入的是地址,不是重新申请局部空间,可以不用return 
    return nums

# TODO如何创建一个大顶堆?
def create(n):
    arr = [0]
    new_index = 1
    arr_ = random.randint(100, size=(n))
    print(arr_)
    '''
    如果数组为空,直接a[1] = elem
    如果数组不空,a[i*2] a[i*2 +1]
        若都空 先左
        若右不空 存右
        平衡二叉树
    '''
    for elem in arr_:
        length = len(arr) - 1
        # 若堆没有元素,直接插入元素,标记域+1
        if len(arr)-1 == 0:
            arr.insert(1,elem)
            length = 1
            continue
        # 如果左子树空,
        if length != new_index*2:
            arr.insert(1,elem)
            length = new_index*2
            reHeap(arr,1,length = length)
            continue
        # 如果右子树空,
        if length != new_index*2 + 1:
            arr.insert(1 ,elem)
            length = new_index*2 + 1
            reHeap(arr,1,length = length)
            new_index = new_index + 1
            continue
    print(arr)
    return arr
print(heapSort(create(5)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值