模板:堆

作點好人好事攢點RP:浙大acm模板.pdfc++

度盤:https://pan.baidu.com/s/1slLnJHFspa

最近看到一個堆的模板(浙大的acm模板),貼過來翻譯

#define MAXN 10000
#define _cp(a,b) ((a)<(b))
typedef int elem_t;
struct heap{
  elem_t h[MAXN];
  int n,p,c;
  void init(){n=0;}
  void ins(elem_t e){
    for (p=++n;p>1&&_cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);
    h[p]=e;
  }
  int del(elem_t& e){
    if (!n) return 0;
    for
      (e=h[p=1],c=2;c<n&&_cp(h[c+=(c<n-1&&_cp(h[c+1],h[c]))],h[n]);h[p]=h[c],p=c,c<<=1);
    h[p]=h[n--];return 1;
  }
};

代碼卻是寫的很好,又快又短,並且封裝性很好,水平和我看過的幾個STL原型差很少了調試

至少比我寫的又慢又長並且封裝性差的一批(最重要的是我打的是錯的)的堆寫的好多了code

然而很難懂,若是硬背的話估計會打錯,要是打錯了估計調試一生都調不出來blog

因此我就手動把這些代碼翻譯成了正常的(誤)C++語言get

首先來一個我本身打的堆(調試了一上午終於打對了)原型

#include <stdio.h>
#define MAXN 3000000
#define SWAP(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
struct heap {
  int H[MAXN], cnt;
  inline void push(int a) {
    int s, f;
    H[++cnt] = a;
    s = cnt, f = (s>>1); 
    while(s > 1 && H[s] < H[f]) {
      SWAP(H[s], H[f]);
      s = f;
      f = (s>>1); 
    }
  }
  inline int pop() {
    if(cnt < 1) return -1; 
    int ret = H[1];
    H[1] = H[cnt--];
    int s = 2, f = 1;
    while(s <= cnt) {
      if(s < cnt && H[s] > H[s+1]) s++;
      if(H[f] > H[s]) {
    SWAP(H[s], H[f]);
    f = s;
    s <<= 1; 
      }
      else break;
    }
    return ret; 
  }
};

而後來一個用正常C++翻譯過來的浙大模板:it

#define MAXN 10000
#define _cp(a,b) ((a)<(b))
typedef int elem_t;
struct heap{
  elem_t h[MAXN];
  int n,p,c;
  void init(){n=0;}
  void ins(elem_t e){
    for (p=++n;p>1&&_cp(e,h[p>>1]);h[p]=h[p>>1],p>>=1);
    h[p]=e;
  }
    //前面都看的懂吧就只加幾個註釋,不改了
    //p = ++n: p是當前兒子節點,++n是堆的末尾位置
    //p > 1:即p>>1 > 0,總不能超出堆的範圍吧
    //_cp(e, h[p>>1]:由於這個實現是替換父子元素,因此若是插入的地方比插入的元素大,就把重複的地方替換掉,結束
    //h[p] = h[p>>1]:替換父子元素
    //p >>= 1: 跳上去
    //h[p] = e:插入的地方比插入的元素大,那麼就替換掉重複的子節點,結束。
    //具體還不清楚的畫一條鏈模擬一下就清楚了
    //實在不懂就看看這個硬式翻譯的ins2吧
  void ins2(elem_t e) {
    p = ++n; 
    while(p > 1 && e < h[p>>1]) {
      h[p] = h[p>>1]; 
      p >>= 1; 
    }
    h[p] = e; 
  }

  int del(elem_t& e){
    if (!n) return 0;
    for
      (e=h[p=1],c=2;c<n&&_cp(h[c+=(c<n-1&&_cp(h[c+1],h[c]))],h[n]);h[p]=h[c],p=c,c<<=1);
    h[p]=h[n--];return 1;
  }
  int del2(elem_t& e) {
    if(!n) return 0; 
    p = 1; 
    c = 2; 
    e = h[p]; 
    while(c <= n-1) {
      if(c < n-1 && h[c+1] < h[c]) c++; 
      if(h[c] >= h[n]) break; 
      h[p] = h[c]; 
      p = c; 
      c <<= 1; 
    }
    h[p] = h[n--]; 
    return 1; 
  }
  //我真不知道這我的類是如何把這麼多代碼縮到一個for裏面去的,zyys
}; 
相關文章
相關標籤/搜索