【算法学习】老算法,新姿势,STL——Heap

“堆”是一个大家很熟悉的数据结构,它可以在\(O(log\;n)\)的时间内维护集合的极值。

这都是老套路了,具体的内部实现我也就不谈了。

我一般来说,都是用queue库中的priority_queue,也就是STL的优先队列来实现堆的,然而最近我发现了一个新的STL容器,它相对优先队列有着更小的常数和更方便的操作。

它就是heap,就是堆。

关于heap,STL提供了4个函数,它们都定义于algorithm库中。它们分别是:

sort一样,其中_First_Last都是头,尾指针或迭代器(对应vector或queue),而_Cmp表示了元素间的大小关系函数。

类似sort,堆中的元素是[_First, _Last)的区间,若内存不连续,也至少要是可随机访问的迭代器(如vector)。

其中_Cmp不是必要的。

还需注意这些函数维护的均是大根堆(即父亲值比孩子大的堆,也称最大堆)。

建立堆:

make_heap(_First, _Last, _Cmp)

在堆中添加元素:

push_heap(_First, _Last, _Cmp)

要先添加元素,再调用函数。

在堆中删除元素:

pop_heap(_First, _Last, _Cmp)

要先调用函数,再删除(不删也可以,只要保证不会出现内存泄漏或者其它bug)。

堆排序:

sort_heap(_First, _Last, _Cmp)

排完序,就像普通的sort一样了,变成有序数组了。不再具有堆的性质。

咚咚咚,代码以后再贴

时间: 2024-08-24 14:34:50

【算法学习】老算法,新姿势,STL——Heap的相关文章

算法学习——分治算法

这是从网上查到的概念资料,先收来~ 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个

算法学习-排序算法

数据结构-算法复杂度 时间复杂度 事件频度 一个算法花费的时间与算法种语句的执行次数成正比,哪个算法种语句执行次数多,它花费时间就多. 一个算法中的语句执行次数称为语句频度或时间频度.记为T(n) eg:计算1-100的和 方法一:for循环 T(n) = n + 1 方法二:直接计算 T(n) = 1 时间复杂度 一般情况下,算法中的基本操作语句的重复执行次数时问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n) / f(n) 的极限值为不等于0的常

[算法学习笔记]算法基础知识

算法基础知识 算法的五大要素 有穷性:算法必须能够在有限个步骤内完成. 确定性:算法的每一步必须有确定的定义. 输入 输出 可行性:算法的每个步骤都必须能分解为基本的可执行操作,每个步骤都必须能在有限时间内完成 循环不变式 循环中的循环不变式可以帮助我们理解算法的正确性.为了证明算法的正确,必须证明循环不变式的三个性质: 1. 初始化:循环不变式在循环开始之前是正确的. 2. 保持:循环不变式在循环的每一次迭代开始之前是正确的. 3. 终止:在循环结束时,不变式会给出一个可以对判断算法是否正确有

算法学习之算法的引入

一.算法的起始 1.第一次尝试 如果 a+b+c=1000,且 a^2+b^2=c^2(a,b,c 为自然数),如何求出所有a.b.c可能的组合? (可以考虑到百钱白鸡)  枚举法 # 注意是三重循环 import time start_time = time.time() for a in range(0, 1001): for b in range(0, 1001): for c in range(0, 1001): if a**2 + b**2 == c**2 and a+b+c == 1

Java算法学习-----------------归并排序算法

将数组中的相邻元素两两配对,用归并算法进行排序,构成n/2组长度为2的排好序的子数组段,然后再将其排成长度为4的子数组段,如此继续下去直到整个数组排好序. 按照此思想,消除递归后的归并排序算法(伪代码)如下: public class MergeSort { public static void mergeSort(Comparable[]a) { Comparable[]b=new Comparable[a.length]; int s=1; while (s<a.length) { merg

算法学习——贪心算法之删数字(求最大值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最大值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若是下一位比上一位大,则比上一位的数字移出,结束之后再次从最高位开始 例如 16489657 删除4个数字 首先比较1和6 删除1 得到 6489657 之后,再次比较 6和4 往后推 可得到 689657 以此类推 删除4个数字之后 可得到 96

算法学习——贪心算法之删数字(求最小值)

算法描述 在给定的n位数字,删除其中的k位数字( k < n),使得最后的n-k为数字为最小值(原次序不变) 算法思路 考虑到是要移出数字,我们使用链表设计此算法较为方便,链表可以直接移出某个位置的元素 使用贪心算法,每一步都要达到最优 从最高位开始,若下一位比上一位要小,则将上一位的数字移出,结束之后再次从最高位开始 这里需要注意,会有特例 当输入从小到大的的一个数的时候,上述算法将会无法运行,比如123456,删除1个数字变为最小,我们把6删去,这样才是最小的(即从末尾删除数字) 算法实现

算法学习——贪心算法之可拆背包

算法描述 已知道n种物品和一个可容纳c重量的背包,第i种物品的重量为wi,价值为pi,装包的时候可以把物品拆开(即可只装每种物品的一部分),设计如何装包,使装包所得整体的价值最高? 算法思路 首先,我们要知道,n种物品以及他们对应的价值,都是由用户输入的 我们使用贪心算法,每一步取最大效益的物品放入背包之中(及单位价值为最高的物品 单位价值=pi/wi) 由以上思路,我们可以定义一个二维数组来接收用户输入的数值 w[i][0] 代表了第i种物品的重量(即wi) w[i][1] 代表了第i种物品的

算法学习——贪心算法之币种统计

算法描述 币种统计 单位给每一位员工发工资(精确到元),为了保证不临时换零钱,使得每个员工取款的张数最少,在取工资前统计所有员工所需要的各种票面的张数(约定票种为100,50,20,10,5,2,1元),并验证币种统计是否正确 算法思路 算法描述其实是省略了要求,用户肯定是要输入员工数以及各位员工的工资 定义:n位员工,G[n]对应了第n员工的工资 a数组存放100元到1元的面值,a[0]=100,a[1]=50... b数组对应每个面值的张数,b[0]对应100元的张数,b[1]对应50元的张

算法学习——双指针算法(最长连续不重复子序列)

双指针算法本质上就是将具有单调性的算法复杂度为O(N^2)的朴素算法通过双指针优化到O(n)的一种优化方法.是一种十分常用的算法. 设计双指针算法我们一般先写出它的朴素算法,然后按照模板: for( int i = 0, j = 0 ; i < n ; i ++) { //check()是按照题目逻辑的判断函数 while( j <= i && check() ){ //不满足时 j ++; } //此处是按照题目逻辑的解答过程. } 将其转换为双指针算法. 例题:最长连续不重