堆排序

    技术2026-01-01  1

    堆排序

    """ 堆排序: 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。 堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。 堆排序可以说是一种利用堆的概念来排序的选择排序。 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 根节点大于两个子节点的值 小顶堆:arr[i] <= arr[2i+1] && arr[i] <= arr[2i+2] 根节点小于两个子节点的值 堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。 --> 有两个构造堆的过程:一个是初始数组构造成堆(不断从后面插入),另一个是堆顶与末尾元素互换后重新构造堆(从头向下比较) 将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。 如此反复执行,便能得到一个有序序列了 1.首先将待排序的数组构造成一个大根堆,此时,整个数组的最大值就是堆结构的顶端 2.将顶端的数与末尾的数交换,此时,末尾的数为最大值,剩余待排序数组个数为n-1 3.将剩余的n-1个数再构造成大根堆,再将顶端数与n-1位置的数交换,如此反复执行,直到只剩下一个元素为止,便能得到有序数组 """ # 将初始数组构造成大根堆(通过新插入的数上升) def heapInsert(arr): """将待排序数组构造成一个大根堆,每次插入新的数据的时候,都与它的父节点进行比较, 如果比父节点的值大,则进行交换,然后继续与新的父节点进行比较,直到小于等于父节点,或者到达顶端; 如果比父节点小,则插入就可以了 """ for i in range(len(arr)): # 遍历数组 currentIndex = i # 记录当前索引 # 计算父节点 fatherIdx = int((currentIndex - 1) / 2) # 当前节点与父节点的值进行比较 while arr[currentIndex] > arr[fatherIdx]: # 当前值比父节点大 # 进行交换 arr[currentIndex],arr[fatherIdx] = arr[fatherIdx],arr[currentIndex] # 更改当前的索引 currentIndex = fatherIdx # 重新计算父节点 fatherIdx = int((currentIndex - 1) / 2) # 直到当前节点到达顶端或者比父节点小,插入下一个 # 固定最大值,将剩余的数再次构造成大根堆,这属于一个循环操作,可以使用递归实现,直到只剩下一个元素结束 def heapify(arr,index,size): """将顶端的最大值与数组末尾的数交换,重新构造大根堆,通过顶端的数下降来重新构造""" # 计算当前index的左右子节点,index总是从根节点0开始 left = 2 * index + 1 right = 2 * index + 2 while left < size: # 当存在左孩子的时候,可以进行重新构造 # 拿到子节点中较大值的索引 largeIdx = 0 if arr[left] < arr[right] and right < size: # 右孩子存在并且右孩子大于左孩子,右子节点的索引值不能超过数组长度size(说明右孩子存在) largeIdx = right else: # 没有右孩子或者左孩子值较大 largeIdx = left # 如果当前父节点的值比较大孩子节点大,当前父节点,说明只有当前这个父节点的子树发生了变化 if arr[index] > arr[largeIdx]: # 当父节点已经是最大,说明已经构成大根堆 break else: # 继续修改当前父节点的子树 # 如果父节点的值比孩子节点小,进行交换 arr[index],arr[largeIdx] = arr[largeIdx],arr[index] # 更改父节点的索引指向 index = largeIdx # 继续与新的子节点进行比较 left = 2 * index + 1 right = 2 * index + 2 # 进行堆排序 def heapSort(arr): # 构造大根堆 heapInsert(arr) size = len(arr) # 固定最大值,再次构造大根堆 while size > 1: arr[0],arr[size-1] = arr[size - 1],arr[0] # 最大值与末尾元素交换 size = size - 1 # 元素长度少了最大值 heapify(arr,0,size) # 重新构造大根堆 return arr if __name__ == '__main__': a = [1,5,7,4,12,36,48,1,2,4,78,89,6,100] print(heapSort(a))
    Processed: 0.011, SQL: 9