堆的 两种实现 (数组和STL)

基本思想: 两种操作都跟树的深度成正比,所以复杂度  O(log(n)) ;

push():在向堆中插入数值时,首先在堆的末尾插入该数值,然后不断向上提直到没有大小颠倒为止。

pop(): 从堆中取出一个数值时,首先把堆的最后一个节点的数值复制到根节点上,并且删除最后一个节点,然后不断向下交换直到没有大小颠倒为止,在向下交换的时候,如果有两个儿子,那就选择数值较小的(如果可以交换的话)进行交换。

数组实现:

 1 #include <cstdio>
 2 const int maxn = 10000;
 3 int heap[maxn], sz=0;
 4
 5 void push(int x) {
 6     int i = sz++;
 7     while(i > 0) {
 8         int p = (i-1) / 2;  //p是父亲节点的编号
 9         if(heap[p] <= x) break;  //如果没有大小颠倒则退出
10         heap[i] = heap[p];  //把父亲节点 放下来 ,而把自己提上去
11         i = p;
12     }
13     heap[i] = x;  //把 x放入 正确的位置
14 }
15
16 int pop() {
17     int ret = heap[0]; //最小值
18     int x = heap[--sz]; //要提到根的数值
19
20     int i = 0;  //从根开始向下交换
21     while(i * 2 + 1 < sz) {   //可能 只有 一个  儿子
22         int a = i * 2 + 1, b = i * 2 + 2;  //两个儿子的 编号
23         if(b < sz && heap[b] < heap[a]) a=b;  //如果 右儿子存在 并且 值比 左儿子小 则交换
24         if(heap[a] >= x) break; //如果不能交换 就退出
25         heap[i] = heap[a];  //把儿子的  数值提上来
26         i=a;
27     }
28     heap[i] = x;
29     return ret;
30 }
31
32 int main()
33 {
34     push(1);
35     push(2);
36     push(10);
37     push(7);
38     push(4);
39
40     int x1 = pop();
41     int x2 = pop();
42
43     printf("%d %d\n",x1,x2);
44     for(int i = 0; i< sz; i++)
45         printf("%d ", heap[i]);
46     return 0;
47 }

STL:

priority_queue 默认取出的是最大值。

priority_queue<int, vector<int>, greater<int> >que; 从小到大

priority_queue<int, vector<int>, less<int> >que;     从大到小

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4
 5 int main() {
 6     priority_queue<int> que;
 7
 8     que.push(5);
 9     que.push(2);
10     que.push(1);
11
12     while(que.size()) {
13         cout << que.top() << endl;
14         que.pop();
15     }
16     return 0;
17 }
时间: 2024-10-08 08:06:31

堆的 两种实现 (数组和STL)的相关文章

两种js数组去重的方法

方法一: 新建一个数组,遍历原数组,在新数组内用IndexOf查找原数组内的每一项,如果没有找到,则添加到其中 代码如下: function arrayNew(arrs ){ var newArray = []; for(var i=0;i<arrs.length;i++){ if(newArray.indexOf){ if(newArray.indexOf(arrs[i])==-1){newArray.push(arrs[i])} } else{ if(indexOf(arrs[i],newA

定义字符串的两种方式

定义字符串的两种方式 数组定义 char name[] = "answer" 指针定义 char *name = "answer" 比较 字符串里的字符可以修改,而字符串是一个常量,字符串里面的字符不能修改. >Tips:可以与我的另外一篇文章一起看.http://blog.csdn.net/u011192270/article/details/46475981 版权声明:本文为博主原创文章,未经博主允许不得转载.

二叉搜索树的两种实现(数组模拟,STL)

书上实现: 二叉搜索数的特点:高效实现 插入一个数值,查询是否包含某个数值,删除某一个数值. 所有的节点都满足左子树上的所有节点都比自己的小,而右子树上的所有节点都比自己大的特点. 查询:如果当前数值等于根节点返回true,比根节点小,就往左儿子走,否则往右儿子走. 插入:按照查找数值的方法去找其所在位置,从根节点出发,往左右儿子中找到合适位置. 删除:需要删除的节点没有左儿子,那么就把右儿子提上去. 需要删除的节点的左儿子没有右儿子,那么就把左儿子提上去 以上两种情况都不符合的话,就把左儿子的

OC中动态创建可变数组的问题.有一个数组,数组中有13个元素,先将该数组进行分组,每3个元素为一组,分为若干组,最后用一个数组统一管理这些分组.(要动态创建数组).两种方法

<span style="font-size:24px;">//////第一种方法 // NSMutableArray *arr = [NSMutableArray array]; // for (int i = 0; i < 13; i ++) { // [arr addObject:[NSString stringWithFormat:@"lanou%d",i + 1]]; // } // NSLog(@"%@",arr);

C++函数传递数组的两种方式

数组与指针. 传首地址过去,然后通过地址输出数组元素. 1.一维数组 #include<iostream> using namespace std; #include <cstring> void farray1(int array1[],int len)//注:此处是无法通过array1得到长度的,只能通过传参,因为其是数组首地址. { for(int i=0;i<len;i++) { //cout<<array1[i]<<endl; cout<

矩阵或多维数组两种常用实现方法 - python

在python中,实现多维数组或矩阵,有两种常用方法: 内置列表方法和numpy 科学计算包方法. 下面以创建10*10矩阵或多维数组为例,并初始化为0,程序如下: # Method 1: list arr1 = [[0]*10 for i in range(10)] arr1[0][0] = 1 print "Method 1:\n", arr1 arr2 = [[0 for i in range(10)] for i in range(10)] arr2[0][0] = 1 pri

【转】java中byte数组与int类型的转换(两种方式)----不错

原文网址:http://blog.csdn.net/piaojun_pj/article/details/5903009 java中byte数组与int类型的转换,在网络编程中这个算法是最基本的算法,我们都知道,在socket传输中,发送.者接收的数据都是 byte数组,但是int类型是4个byte组成的,如何把一个整形int转换成byte数组,同时如何把一个长度为4的byte数组转换为int类型.下面有两种方式. 第一种方法: public static byte[] int2byte(int

二维数组的认识及其表示元素的两种方式

/* ============================================================================ Name : TeatArr.c Author : lf Version : Copyright : Your copyright notice Description : 二维数组的认识以及其表示元素的两种方式 备注说明 1 要理解二维数组的存储方式. 2 实际上利用a[i][j]的方式并不"正统",这是这靠近我们的 常识一些

PHP中数组合并的两种方法及区别介绍

PHP数组合并两种方法及区别 如果是关联数组,如下: 复制代码代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = array( 'where' => 'uid=2', 'order' => 'uid desc', ); 1. array_merge,如果两个数组存在相同的key,后面的一个会覆盖前面的 复制代码代码如下: <?php $c = array_merge($a, $b); var_expo