zoukankan      html  css  js  c++  java
  • 常用排序算法:堆排序

    算法思路:

    堆:分为大根堆和小根堆
           大根堆:一棵完全二叉树,满足任意一节点都比其孩子节点大。
           小根堆:一棵完全二叉树,满足任意一节点都比其孩子节点小。

    堆排序流程: 

    1. 构造堆
    2. 得到堆顶元素,为最大元素
    3. 去掉堆顶,将堆的最后一个元素放到堆顶,然后调整重新使堆有序
    4. 堆顶元素为第二大的元素
    5. 重复第三步直到堆变空

    例如以[4, 5, 3, 6, 1, 2 ]为例:

    准备知识:

         在以顺序储存的完全二叉树中,父子节点的关系(下标):

    1. 父节点和左孩子:左孩子下标 = 父节点下标 * 2 + 1
    2. 父节点和右孩子:右孩子下标 = 父节点下标 * 2 + 2
    3. 子节点和父节点: 父节点下标 = (子节点下标 - 1)  // 2
    4. 最后一个非叶子节点:n // 2 -1

    代码实现:  

    def sift(nums, low, high):
        """
        调整堆,使堆有序
        :param nums: list
        :param low: 根节点
        :param high: 尾节点(树的最后一个)
        :return:
        """
        temp = nums[low]
        i = low
        j = 2 * i + 1
        while j <= high:  # 当前i位置为叶子节点, j超过high了
            # 找更大的子节点
            if j + 1 <= high and nums[j+1] > nums[j]:  #
                j = j + 1
            if temp < nums[j]:
                nums[i] = nums[j]
                i = j
                j = 2 * i + 1
            else:   # temp 大于两个子节点
                break
        nums[i] = temp
    
    
    def heap_sort(nums):
        # 建堆
        l = len(nums)
        for i in range(l//2-1, -1, -1):
            # i是建堆时要调整的子树的根节点下标
            sift(nums, i, l-1)
        for i in range(l - 1, -1, -1):
            # 当前的high值
            nums[i], nums[0] = nums[0], nums[i]
            sift(nums, 0, i-1)

    内置函数:

    Python内置模块heapq帮我们实现了堆排序,内置函数用的是小根堆,上面的代码是大根堆,差别不大,heapq模块主要包括三个函数:

    1. heapify(list) 建小根堆   把传入的list变成小根堆

    2. heappush(heap_list, item)向已经建好的堆中增加数据

    3. heappop(heap_list) 输出小根堆中最小值

    import heapq
    
    nums = [3, 2, 1, 0, 6]
    
    heapq.heapify(nums)
    print(nums)
    # [0, 2, 1, 3, 6]
    heapq.heappush(nums, 4)
    print(nums)
    # [0, 2, 1, 3, 6, 4]
    print(heapq.heappop(nums))
    # 0
    print(heapq.heappop(nums))
    # 1
    print(heapq.heappop(nums))
    # 2
  • 相关阅读:
    剑指OFFER----面试题37. 序列化二叉树
    剑指OFFER----面试题36. 二叉搜索树与双向链表
    剑指OFFER----面试题35. 复杂链表的复制
    6.深拷贝与浅拷贝
    DevExpress ASP.NET v19.1版本亮点:发布全新的Gantt控件
    MFC界面库BCGControlBar v30.1新功能详解:Dialogs和Forms
    Kendo UI for jQuery使用教程:支持Web浏览器
    DevExpress Windows 10 v19.1新版亮点:UWP控件新功能全面解析
    Java 11必掌握的8大特性,完美代码信手拈来
    Kendo UI for jQuery使用教程:入门指南
  • 原文地址:https://www.cnblogs.com/FanMLei/p/10500997.html
Copyright © 2011-2022 走看看