zoukankan      html  css  js  c++  java
  • 《数据结构与算法分析:C语言描述》复习——第五章“堆”——二叉堆

    2014.06.15 22:14

    简介:

      堆是一种非常实用的数据结构,其中以二叉堆最为常用。二叉堆可以看作一棵完全二叉树,每个节点的键值都大于(小于)其子节点,但左右孩子之间不需要有序。我们关心的通常只有堆顶的元素,而整个堆则被封装起来,保存在一个数组中。

    图示:

      下图是一个最大堆:

      

    实现:

      优先队列是STL中最常用的工具之一,许多算法的优化都要利用堆,使用的工具就是优先队列。STL中的优先队列通过仿函数来定义比较算法,此处我偷懒用了“<”运算符。关于使用仿函数的好处,我之后如果有时间深入学习STL的话,再写博文分析吧。

      1 // My implementation for priority queue using binary heap.
      2 #include <iostream>
      3 #include <string>
      4 #include <vector>
      5 using namespace std;
      6 
      7 template <class T>
      8 class PriorityQueue {
      9 public:
     10     PriorityQueue() {
     11         m_data.push_back(0);
     12     }
     13     
     14     PriorityQueue(const vector<T> &data) {
     15         m_data.push_back(0);
     16         for (size_t i = 0; i < data.size(); ++i) {
     17             m_data.push_back(data[i]);
     18         }
     19         _makeHeap();
     20     }
     21     
     22     bool empty() {
     23         return m_data.size() == 1;
     24     }
     25     
     26     size_t size() {
     27         return m_data.size() - 1;
     28     }
     29     
     30     T top() {
     31         return m_data[1];
     32     }
     33     
     34     void push(const T &val) {
     35         m_data.push_back(val);
     36         
     37         int n = size();
     38         int i = n;
     39         
     40         while (i > 1) {
     41             if (m_data[i / 2] < m_data[i]) {
     42                 _swap(m_data[i / 2], m_data[i]);
     43                 i /= 2;
     44             } else {
     45                 break;
     46             }
     47         }
     48     }
     49     
     50     void pop() {
     51         int n = size();
     52         m_data[1] = m_data[n];
     53         m_data.pop_back();
     54         --n;
     55         
     56         int i = 1;
     57         T max_val;
     58         while (i * 2 <= n) {
     59             max_val = i * 2 == n ? m_data[i * 2] : _max(m_data[i * 2], m_data[i * 2 + 1]);
     60             if (m_data[i] < max_val) {
     61                 if (max_val == m_data[i * 2] || i * 2 == n) {
     62                     _swap(m_data[i], m_data[i * 2]);
     63                     i = i * 2;
     64                 } else {
     65                     _swap(m_data[i], m_data[i * 2 + 1]);
     66                     i = i * 2 + 1;
     67                 }
     68             } else {
     69                 break;
     70             }
     71         }
     72     }
     73     
     74     void clear() {
     75         m_data.resize(1);
     76     }
     77 
     78     ~PriorityQueue() {
     79         m_data.clear();
     80     }
     81 private:
     82     vector<T> m_data;
     83     
     84     T _max(const T &x, const T &y) {
     85         return x > y ? x : y;
     86     }
     87     
     88     void _swap(T &x, T &y) {
     89         T tmp;
     90         
     91         tmp = x;
     92         x = y;
     93         y = tmp;
     94     }
     95     
     96     void _makeHeap() {
     97         int n = size();
     98         int i, j;
     99         T max_val;
    100         
    101         for (j = n / 2; j >= 1; --j) {
    102             i = j;
    103             while (i * 2 <= n) {
    104                 max_val = i * 2 == n ? m_data[i * 2] : _max(m_data[i * 2], m_data[i * 2 + 1]);
    105                 if (m_data[i] < max_val) {
    106                     if (max_val == m_data[i * 2] || i * 2 == n) {
    107                         _swap(m_data[i], m_data[i * 2]);
    108                         i = i * 2;
    109                     } else {
    110                         _swap(m_data[i], m_data[i * 2 + 1]);
    111                         i = i * 2 + 1;
    112                     }
    113                 } else {
    114                     break;
    115                 }
    116             }
    117         }
    118 
    119         n = size();
    120         cout << '[';
    121         for (int i = 1; i <= n; ++i) {
    122             cout << m_data[i] << ' ';
    123         }
    124         cout << ']' << endl;
    125     }
    126 };
    127 
    128 int main()
    129 {
    130     vector<int> v;
    131     v.push_back(1);
    132     v.push_back(2);
    133     v.push_back(3);
    134     v.push_back(4);
    135     v.push_back(5);
    136     v.push_back(6);
    137     v.push_back(7);
    138     v.push_back(8);
    139     PriorityQueue<int> pq(v);
    140     string s;
    141     int n;
    142     
    143     while (cin >> s) {
    144         if (s == "push") {
    145             cin >> n;
    146             pq.push(n);
    147         } else if (s == "pop") {
    148             pq.pop();
    149         } else if (s == "top") {
    150             cout << pq.top() << endl;
    151         } else if (s == "end") {
    152             while (!pq.empty()) {
    153                 pq.pop();
    154             }
    155             break;
    156         }
    157     }
    158     
    159     return 0;
    160 }
  • 相关阅读:
    win10开机时内存使用率达到99%以上
    https的基本原理,看完你的程序员女朋友再也不和你提分手了
    Tomcat样例安全漏洞
    Linux5355端口被0.0.0.0监听
    jQuery的ajax
    事件委托(事件代理)
    jQuery的事件绑定和解绑
    事件对象
    JS的事件流的概念(重点)
    jQuery的位置信息
  • 原文地址:https://www.cnblogs.com/zhuli19901106/p/3790119.html
Copyright © 2011-2022 走看看