Python数据结构与算法笔记-堆排序

https://www.bilibili.com/video/BV1uA411N7c5
以下内容均为上面视频学习笔记

堆排序

注意:后面的堆,二叉树,里面不用关注里面的数据,只是一个混乱的二叉树。是需要配合下面的堆的方法(向下调整)进行排序调整。

基本概念

在这里插入图片描述

存储方式

分为两种:

  • 链式存储
  • 顺序存储

根堆

在这里插入图片描述
大根堆:增序排列的
小根堆

堆的向下调整

将大的数换到最上面,重新调整位置,即为堆的向下调整

挨个出数

构造堆

在这里插入图片描述

在这里插入图片描述

堆排序过程

在这里插入图片描述

1、主函数

这个部分代码会有拆解,都是在head_sort 方法的

总的函数

1、构建堆
def head_sort(li):
    # 1、构建堆
    n = len(li)
    for i in range((n - 2) // 2, -1, -1):
        # i 表示调整的部分的根的下标
        sift(li, i, n - 1)
        # 将hight 传n-1 省去计算hight的一步,n-1 只是作为一个判断条件,可以参考sift函数
    	print(li)

li = list(range(20))
random.shuffle(li)
head_sort(li)
2、挨个出数
def head_sort(li):
    # 1、构建堆
    n = len(li)
    for i in range((n - 2) // 2, -1, -1):
        # i 表示调整的部分的根的下标
        sift(li, i, n - 1)
        # 将hight 传n-1 省去计算hight的一步,n-1 只是作为一个判断条件,可以参考sift函数
    
    # 2。挨个出数
    for i in range(n - 1, -1, -1):
        # i 指向当前最后一个元素
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i - 1)

li = list(range(20))
random.shuffle(li)
head_sort(li)

2、调整函数

def sift(li, low, hight):
    '''
    调整函数
    :param li: 列表
    :param low: 堆的根节点
    :param hight: 堆最后一个元素的位置
    :return:
    '''
    
    leader = low  # 最开始指向根节点
    people = 2 * low + 1  # people 最开始是左孩子
    tmp = li[low]  # 把堆顶存起来
    while people <= hight:  # people 的位置需要有数据,不能大于最大元素index
        if people + 1 <= hight and li[people + 1] > li[people]:  # 如果右边孩子存在,并且比左孩子大
            people = people + 1  # 则取右孩子
        
        if li[people] > tmp:
            li[leader] = li[people]
            leader = people  # 往下再走一层
            people = 2 * leader + 1
        else:  # tmp 更大,退出
            break
    li[leader] = tmp  # 把tmp 放回领导岗位,也就是根节点


全部实现代码

import random


def sift(li, low, hight):
    '''
    调整函数
    :param li: 列表
    :param low: 堆的根节点
    :param hight: 堆最后一个元素的位置
    :return:
    '''
    
    leader = low  # 最开始指向根节点
    people = 2 * low + 1  # people 最开始是左孩子
    tmp = li[low]  # 把堆顶存起来
    while people <= hight:  # people 的位置需要有数据,不能大于最大元素index
        if people + 1 <= hight and li[people + 1] > li[people]:  # 如果右边孩子存在,并且比左孩子大
            people = people + 1  # 则取右孩子
        
        if li[people] > tmp:
            li[leader] = li[people]
            leader = people  # 往下再走一层
            people = 2 * leader + 1
        else:  # tmp 更大,退出
            break
    li[leader] = tmp  # 把tmp 放回领导岗位,也就是根节点


def head_sort(li):
    # 1、构建堆
    n = len(li)
    for i in range((n - 2) // 2, -1, -1):
        # i 表示调整的部分的根的下标
        sift(li, i, n - 1)
        # 将hight 传n-1 省去计算hight的一步,n-1 只是作为一个判断条件,可以参考sift函数
    
    # 2。挨个出数
    for i in range(n - 1, -1, -1):
        # i 指向当前最后一个元素
        li[0], li[i] = li[i], li[0]
        sift(li, 0, i - 1)


li = list(range(20))
random.shuffle(li)
head_sort(li)

Python 第三方库heapq (了解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值