zoukankan      html  css  js  c++  java
  • 堆的 两种实现 (数组和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
    ",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 }
  • 相关阅读:
    Ubuntu 11.10版本下的软件中心安装软件的默认路径
    C++中构造函数调用与申明方式的关系
    VMware Workstation 虚拟机(客户机)创建和主机共享文件夹
    观察者模式——三英雄战吕布
    如何在yarn上运行Hello World(二)
    Cat 客户端如何构建调用链消息树
    Cat 跨线程之 TaggedTransaction 用法和原理分析
    Cat 客户端采用什么策略上报消息树
    Cat 跨线程之 ForkedTransaction 用法和原理分析
    jest for elasticsearch
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4479046.html
Copyright © 2011-2022 走看看