作點好人好事攢點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 };