zoukankan      html  css  js  c++  java
  • Python:堆排序

    相关概念

    堆是一种完全二叉树,即按从上到下,从左到右生成的二叉树。

    堆有两种类型: 大根堆,小根堆。

    大根堆:每个结点的值都大于或等于左右孩子结点。

    小根堆:每个结点的值都小于或等于左右孩子结点。

    计算某个节点的父节点和两个子节点

    如上图,选取3这个节点,他的序号:i = 3

    父节点:parent = ( i - 1 ) / 2 = 1 (这里进行的是取整)

    左子节点:c1 = 2i + 1 = 7

    右子节点:c2 = 2i + 2 = 8

    堆排序的步骤

    第一步:能够将某一节点及其子节点堆化(heapify);

    第二步:从最后一个父节点开始,向前对他们进行第一步操作,最终得到一个大根堆;

    第三步:将根节点值(最大值)和最后一个节点值进行交换;

    第四步:将除最后一个节点外的元素,进行堆化操作。

    # 堆化某一节点和其子节点
    def heapify(tree, node, i):
    
        # 对 i 节点进行堆化,i 是 parent 节点
        # 需要找到 i 的两个子节点
        c1 = 2 * i + 1
        c2 = 2 * i + 2
    
        # 需要找出 i,c1,c2 这三个节点中的最大值
        # 先假设 i 为最大值
        max_node = i
    
        # 判断 c1和c2 是否存在,找到最大值的下标,即max_node
        if c1 < node and tree[c1] > tree[max_node]:
            max_node = c1
        if c2 < node and tree[c2] > tree[max_node]:
            max_node = c2
    
        # max_node 不等于 i,则说明存在子节点大于 i这个父节点
        # 将这个子节点的值和父节点的值进行交换,最大值成为根节点
        if max_node != i:
            tree[i], tree[max_node] = tree[max_node], tree[i]
            heapify(tree, node, max_node)
    
    
    # 堆排序
    def heapSort(arr):
        n = len(arr)
        last_parent = (n - 2) // 2
    
        # 从最后一个父节点开始向前进行 heapify 操作
        # 将 arr 堆化,最大值成为根节点
        for i in range(last_parent, -1, -1):
            heapify(arr, n, i)
    
        for i in range(n - 1, 0, -1):
            # 将根节点和最后一个节点进行值交换
            arr[i], arr[0] = arr[0], arr[i]
            # 剩下的 i 个节点进行 heapify
            heapify(arr, i, 0)
    
    
    lis = [2, 3, 5, 1, 6]
    heapSort(lis)
    print(lis)
  • 相关阅读:
    C++中的名字重整技术
    Linux下C++开发常用命令
    《Effective C++(第三版)》 的55条建议
    我也介绍下sizeof与strlen的区别
    POJ
    HDU
    HDU-1754-I Hate It(单点更新+区间查询)
    HDU多校1003-Divide the Stones(构造)
    Just an Old Puzzle(2019多校1007)
    Idiomatic Phrases Game(最短路+注意坑点)
  • 原文地址:https://www.cnblogs.com/dc2019/p/13615505.html
Copyright © 2011-2022 走看看