自下而上建堆(heap)的时间复杂度证明

作者:Tobin
日期:2019/04/13
缘由:看python cookbook时,用到了heapq的库,书中提到,如果仅仅是返回一个数组的最大值,用max就可以了,但是如果返回多个较大或者较小元素用堆,如果返回的个数接近于数组本身的元素个数时,直接用排序即可。那么我在想,为啥返回几个元素的时候用堆效果比较好呢?于是我翻开了尘封许久的《算法导论》。

什么是堆

堆是一种数据结构。二叉堆是一个数组,近似于一个完全二叉树。树上的每个结点对应于数组的一个元素,除了最底层外树是充满的。下面的图是一个小根堆。即父节点的值要小于子结点,大根堆要相反。

堆有哪些操作?复杂度如何证明。

建堆操作,调整操作,利用前两个进行的堆排序操作(建完堆后,不断将第一个元素与最后一个元素进行交换,然后调整,复杂度O(nlogn)。
主要是想记录下复杂度的证明,具体的堆如何操作就不细讲了,可以参考其它博客。
见图。

复杂度上界是O(2n),在这之后,每次取一个最大元素并剔除后,进行调整的复杂度是O(logn),也就是说在建完堆后,每次需要到最大值得复杂度是O(logn)。显然在返回多个较大元素的情况下,建堆进行操作的速度比遍历要快,遍历每次需要O(n)的时间。

堆有什么作用呢?

优先队列的底层是用堆来实现的。

原文地址:https://www.cnblogs.com/zuotongbin/p/10702001.html

时间: 2024-08-01 00:34:24

自下而上建堆(heap)的时间复杂度证明的相关文章

建堆复杂度O(n)证明

堆排序中首先需要做的就是建堆,广为人知的是建堆复杂度才O(n),不过很少有人去了解过这个复杂度的证明过程,因为不是那么直观地可以一眼就看出来.本文不讲堆排序,只单纯讲建堆过程. 建堆代码 欲了解复杂度的计算过程,必先看懂建堆代码.先看这个建堆过程 // 将arr[n]向上调整至合适位置 void AdjustHeap(vector<int> &arr, int n) { if(n<=0) return ; if(arr[(n-1)/2] > arr[n]) { //与父结点

建堆[HihoCoder-1405]

Building Heap HihoCoder-1405 hihoCoder太阁最新面经算法竞赛11 问题大意:给定一个$N$个元素的数组$A$(元素互不相同),要求你建立满足下列要求的二叉树$T$,并输出其前序遍历: 1)$T$满足最小堆性质: 2)输入的数组$A$满足$T$的中序遍历. 这是一道数据结构基础题,主要是解决如何建堆.题目要求最小堆,其树根必然是整个树的最小值.因此在建堆过程中,只需寻找最小值,根据找到的最小值的位置将中序遍历的序列一分为二,继续对这两个子序列建堆,直到子序列没有

优先队列Priority Queue和堆Heap

对COMP20003中的Priority queue部分进行总结.图片来自于COMP20003 queue队列,顾名思义特点先进先出 priority queue优先队列,出来的顺序按照优先级priority大小,越大(小)的先pop. 普通的方法: Unsorted array: Construct: O(n) Get highest priority: O(n) Sorted array: Construct: O(n2) Get highest priority: O(1) 使用堆heap

堆Heap

#pragma once#include <vector> // 小堆template<class T>  //仿函数struct Less{       bool operator() (const T& l, const T& r)       {             return l < r; // operator<       }}; template<class T>struct Greater{       bool ope

【数据结构】堆heap

本节研究堆heap的相关操作实现: 堆 说明几点 (1)堆分为大根堆和小根堆:大根堆的根为最大值,每一个节点的值都不小于其孩子的值: (2)可以利用大根堆实现升序排序:主要是利用大根堆的头和需要排序的最后一个数字交换的思想: (3)使用大根堆实现最大优先级队列,类似stl中queue的操作,只是对于元素在队列中的元素优先级是不一样的,在最大优先级中,队列头为值最大元素:可利用大根堆来维护一个最大优先级队列:向优先级队列中push元素,类似像堆的末尾添加一个元素,然后使用_makeHeapUp寻找

Python3实现最小堆建堆算法

今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构的时候有个堆排序算法,所以顺便研究了一下“堆”结构(这里特指二叉堆). 概念 所谓二叉堆(binary heap)实际上就是一颗特殊的完全二叉树,其特殊性在于: 二叉树中所有的父节点的值都不大于/不小于其子节点: 根节点的值必定是所有节点中最小/最大的. 父节点值不大于子节点且根节点值最小称为最小堆

编程算法 - 堆(heap) 代码(C)

堆(heap) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 堆(heap)作为二叉树的重要应用, 时间复杂度O(logn), 需要熟练的写出其代码, 基本代码如下, 需要背写. 代码: /* * main.cpp * * Created on: 2014.7.20 * Author: spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> class Heap { static const

编程算法 - 篱笆修理(Fence Repair) 堆(heap) 代码(C++)

篱笆修理(Fence Repair) 堆(heap) 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 题目参考: http://blog.csdn.net/caroline_wendy/article/details/37911157 本题比较简单, 直接使用堆(heap)选取两个最小的值, 合并再放入堆, 最后求出和. 比起贪婪算法O(n^2), 时间复杂度O(nlogn). 代码: /* * main.cpp * * Created on:

Go语言标准库堆(heap)封装及堆排序实现

Go语言的OOP,接口,接口的组合,基础库的函数及接口如何抽象设计, 这些东西在Go的Heap源码及演示例子处理中,都有很好的展示. 在"container/heap"中,它的接口是如下定义的: type Interface interface { sort.Interface Push(x interface{}) // add x as element Len() Pop() interface{} // remove and return element Len() - 1. }