zoukankan      html  css  js  c++  java
  • 20191209-八大排序之堆排序

    1. 堆排序

    算法核心思想

    堆排序利用堆的特点, 最大堆要求节点的元素都要不小于其孩子,最小堆要求节点元素都不大于其左右孩子,那么处于最大堆的根节点的元素一定是这个堆中的最大值,每次把堆顶元素放置在二叉树的尾部,然后重新建堆这样循环处理,最终就能完成排序。

    核心算法逻辑如下:

    1. 建堆
    2. 把堆顶的元素和最后一个元素交换,这样,最大的元素就排到了最后面
    3. 把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置
    4. 重复上面的1到3步,之后遍历完堆

    在堆中,节点i的左子节点是2*i+1,右子节点是2*i+2,故最小值堆满足如下的特点:

    1. Node(i).value < Node(2*i+1).value
    2. Node(i).value < Node(2*i+2).value

    代码实现

    建堆,建堆的过程通过数组的给定数组的下标,建立以给定下标为根的堆,具体过程如下:

    def heapify(arr,root_index,arr_length):
        """给定数组,数组的下标,当前需要建堆的数组长度"""
        left_index = 2*root_index+1
        right_index = 2*root_index+2
        max_index = root_index
        #找到以arr[root_index]为根的堆的与左右子树3个节点中最大值的索引
        if left_index<arr_length and arr[left_index]>arr[max_index]:
            max_index = left_index
        if right_index<arr_length and arr[right_index]>arr[max_index]:
            max_index = right_index
        if max_index!=root_index:
            arr[max_index],arr[root_index] = arr[root_index],arr[max_index]
            heapify(arr,max_index,arr_length)
    def buildheap(arr):
        """从堆的最后一个有子节点的索引开始建堆,然后逐一给堆添加节点"""
        for i in range(len(arr)//2,-1,-1):
            heapify(arr,i,len(arr))

    将堆顶的元素与最后一个元素交换,缩短数组的长度再次建堆,重复直至排序完成

    def heapSort(arr):
        arr_length = len(arr)
        buildheap(arr)#先建堆
        for i in range(arr_length):
            arr[0],arr[arr_length-i-1]= arr[arr_length-i-1],arr[0]
            heapify(arr,0,arr_length-i-1)#此时堆的结构变化,调整堆结构
        return arr

    执行解析

    heapify(arr,root_index,arr_length)函数实现了一个建堆的过程,一定要从堆的最下层节点开始建堆,如果从堆的最上层开始建堆,则该函数无法保证堆的所有节点满足堆的结构

    建立堆后每次取堆顶的元素(arr[0]的位置)放置到第arr_len-i的位置(第一次放置在倒数第一个位置,第二次放置在倒数第二个位置,第n次放置子倒数第n个位置)当最后所有元素放置完成后排序结束。

    1. 使用使用buildheap函数建立第一个最大堆
    2. 使用heapify调整堆结构保证
    3. 使用heapsort实现堆排序的交换

    时间复杂度:O(N*logN)。

    总结

    堆排序的时间复杂度为O(n*logn),堆排序是使用完全二叉树的特点来实现的一种排序方式

  • 相关阅读:
    主题:钩子函数简析及实例
    boa安装
    Inno Setup入门(二十一)——Inno Setup类参考(7)
    Inno Setup入门(二十)——Inno Setup类参考(6)
    Inno Setup入门(十九)——Inno Setup类参考(5)
    Inno Setup入门(十八)——Inno Setup类参考(4)
    Inno Setup入门(十七)——Inno Setup类参考(3)
    Inno Setup入门(十六)——Inno Setup类参考(2)
    sqlite 增加字段语句
    判断 Selite中标存在或者字段存在的方法
  • 原文地址:https://www.cnblogs.com/hyj691001/p/12013391.html
Copyright © 2011-2022 走看看