开个网站多少钱一年学校网站源码
news/
2025/10/2 23:47:50/
文章来源:
开个网站多少钱一年,学校网站源码,西充县企业网站建设,松江网站开发培训学校heap【堆】掌握 手写上浮、下沉、建堆函数 对一组数进行堆排序 直接使用接口函数heapq
什么是堆#xff1f;#xff1f;#xff1f;堆是一个二叉树。也就是有两个叉。下面是一个大根堆#xff1a;
大根堆的每一个根节点比他的子节点都大 有大根堆就有小根堆#xff1…heap【堆】掌握 手写上浮、下沉、建堆函数 对一组数进行堆排序 直接使用接口函数heapq
什么是堆堆是一个二叉树。也就是有两个叉。下面是一个大根堆
大根堆的每一个根节点比他的子节点都大 有大根堆就有小根堆
我们可以看到红9在绿9的下一层大小堆中我们需要注意【只有根节点对子节点的大小比较】没有子节点之间的比较。 一、手写函数
def siftup(heap, pos):endpos len(heap)startpos posnewitem heap[pos]# Bubble up the smaller child until hitting a leaf.childpos 2*pos 1 # leftmost child positionwhile childpos endpos:# Set childpos to index of smaller child.rightpos childpos 1if rightpos endpos and not heap[childpos] heap[rightpos]:childpos rightpos# Move the smaller child up.heap[pos] heap[childpos]pos childposchildpos 2*pos 1# The leaf at pos is empty now. Put newitem there, and bubble it up# to its final resting place (by sifting its parents down).heap[pos] newitemup操作只是将孩子提上去但是没有保证根节点比孩子小现在比较孩子和父节点如果父节点更大往下覆盖孩子节点并且往上继续比较上面的父节点直至到头start将原来的子节点的值覆盖在此时的父节点上。siftdown(heap, startpos, pos)up与down一起维持小根堆性质
def siftdown(heap, startpos, pos):newitem heap[pos]# Follow the path to the root, moving parents down until finding a place# newitem fits.while pos startpos:parentpos (pos - 1) 1parent heap[parentpos]if newitem parent:heap[pos] parentpos parentposcontinuebreakheap[pos] newitemdef heappop(heap):Pop the smallest item off the heap, maintaining the heap invariant.lastelt heap.pop() # raises appropriate IndexError if heap is emptyprint(pop:, lastelt)if heap:returnitem heap[0]heap[0] lasteltsiftup(heap, 0)print(heap:, heap)print(returnitem, returnitem)return returnitemreturn lasteltdef heapify(x):Transform list into a heap, in-place, in O(len(x)) time.n len(x)for i in reversed(range(n//2)):从最后一个根节点开始将孩子节点最小的覆盖根节点并不断往下找将较小的孩子提上来。直到没有孩子将根节点的值覆盖到此时的孩子节点上siftup(x, i)def heap_sort(arr):# 将数组转换为小根堆heapify(arr)print(arr)# 弹出堆顶元素直到堆为空每次pop最后一个节点并输出根节点。将最后一个节点覆盖在根节点上并且进行up——down操作位置小根堆性质return [heappop(arr) for _ in range(len(arr))]if __name__ __main__:# 示例数组arr [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]# 执行堆排序sorted_arr heap_sort(arr)# 打印排序后的数组print(sorted_arr, sorted_arr)
二、调用python接口
import heapq
def heap_sort(arr):# 将数组转换为小根堆heapq.heapify(arr)print(arr)# 弹出堆顶元素直到堆为空每次pop最后一个节点并输出根节点。将最后一个节点覆盖在根节点上并且进行up——down操作位置小根堆性质return [heapq.heappop(arr) for _ in range(len(arr))]if __name__ __main__:# 示例数组arr [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]# 执行堆排序sorted_arr heap_sort(arr)# 打印排序后的数组print(sorted_arr, sorted_arr)
输出 [1, 1, 2, 3, 3, 9, 4, 6, 5, 5, 5] sorted_arr [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9] 三、时间复杂度 siftup(heap, pos) 函数 这个函数将一个元素上浮到它应该在的位置。在最坏的情况下它可能需要上浮到堆的根节点时间复杂度是 O(log n)其中 n 是堆中元素的数量。 siftdown(heap, startpos, pos) 函数 这个函数将一个元素下沉到它应该在的位置。同样在最坏的情况下它可能需要下沉到叶子节点时间复杂度也是 O(log n)。 heappop(heap) 函数 这个函数移除并返回堆顶元素最小元素然后通过调用 siftup 来修复堆。siftup 的时间复杂度是 O(log n)所以 heappop 的时间复杂度也是 O(log n)。 heapify(x) 函数 这个函数将一个数组转换成一个堆。它从最后一个父节点开始向上调用 siftup。由于堆的最后一个父节点的索引是 n/2 - 1n 是数组的长度所以它实际上调用了大约 n/2 次 siftup。因此heapify 的时间复杂度是 O(n)。 heap_sort(arr) 函数 这个函数首先调用 heapify 将数组转换成一个堆然后通过 n 次调用 heappop 来移除所有元素。由于 heapify 的时间复杂度是 O(n)并且 heappop 的时间复杂度是 O(log n)heap_sort 的总时间复杂度是 O(n log n)。 总结 时间复杂度 siftup: O(log n)siftdown: O(log n)heappop: O(log n)heapify: O(n)heap_sort: O(n log n) 整体上对于堆排序算法的时间复杂度分析如下 构建堆Heapifyheapify 函数将数组转换成一个堆。对于一个长度为 n 的数组heapify 的时间复杂度是 O(n)。这是通过从最后一个父节点开始向上调用 siftup 实现的每个 siftup 操作的时间复杂度是 O(log n)但由于堆的结构特性实际上 heapify 的总体时间复杂度是线性的。 堆排序Heap Sort在 heap_sort 函数中首先调用 heapify 将数组转换成一个堆然后通过 n 次调用 heappop 来移除所有元素。每次 heappop 操作的时间复杂度是 O(log n)。因此n 次 heappop 的总时间复杂度是 O(n log n)。 综合以上两点堆排序的整体时间复杂度是 O(n n log n)简化后为 O(n log n)。这是因为在堆排序过程中构建堆是一次性的而移除元素需要 n 次操作每次操作的复杂度是 log n。 空间复杂度O(1)因为所有操作都是原地进行的。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/925422.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!