當前位置:
首頁 >
三叉堆实现堆排序
發布時間:2024/4/17
48
豆豆
1 /*
2 手寫三叉堆
3 */
4 #include<cstdio>
5 #include<iostream>
6 using namespace std;
7
8 class heap3{
9 private:
10 int heap[100001];
11 int heap_size;
12 public:
13 void put(int d);//類比二叉堆的put操作
14 int get();//類比二叉堆的get操作
15 int getsize();//返回當前堆的大小
16 void in(int x,int y);//因題目排序需要,寫了這個函數,作用是將heap數組中的 第x個元素的值 賦值成y
17 void out(int n);//挨個訪問 排序過的堆 中的元素
18 };
19
20 heap3 m;
21
22 void heap3::out(int n){
23 for(int k=1;k<=n;++k) cout<<heap[k]<<' ';
24 }
25
26 void heap3::in(int x,int y){heap[x]=y;}
27
28 void heap3::put(int d)
29 {
30 heap[++heap_size]=d;
31 int now=heap_size,next;
32
33 while(now>1)
34 {
35 next=(now+1)/3;
36 if(heap[now]<=heap[next]) break;
37 swap(heap[now],heap[next]);
38 now=next;
39 }
40
41 return;
42 }
43
44 int heap3::getsize(){return heap_size;}
45
46 int heap3::get(){
47
48 int now=1,next;
49 int res=heap[1];
50 heap[1]=heap[heap_size--];
51
52 while(now*3-1 <= heap_size)
53 {
54 next=now*3-1;
55
56 if(next+1<=heap_size && heap[next+1]>heap[next]){
57 next++;
58
59 if(next+1<=heap_size && heap[next+1]>heap[next]) next++;
60 }
61 else
62 if(next+2<=heap_size && heap[next+2]>heap[next]) next+=2;
63
64 if(heap[now]>=heap[next]) break;
65
66 swap(heap[now],heap[next]);
67 now=next;
68 }
69 return res;
70 }
71
72 int main(){
73 int n,x;
74 scanf("%d",&n);
75 for(int i=1;i<=n;++i){
76 scanf("%d",&x);
77 m.put(x);
78 }
79
80 for(int i=1;i<n;++i){
81 int k=m.getsize();
82 m.in(k,m.get());
83 }
84
85 m.out(n);
86
87 return 0;
88 }
?
關于三叉堆的資料,我是參考的這篇文章 http://www.docin.com/p-902813669.html
推薦大家讀一下。
這篇文章表示:三叉堆比二叉堆更優秀
實際上確實是這樣的,至少我經過實踐,發現用三叉堆對 100000個 數排序,比二叉堆快,
數據均為此題 https://www.luogu.org/problemnew/show/P1177 的數據。
?
?由于是很久之前的代碼了,解釋都是現寫的……
如圖是一個三叉堆:
如果學習了二叉堆,理解三叉堆就變得很容易,因為原理都是一樣的,解釋都在注釋里了,關于三叉堆,只有以下需要強調的了:
在數組中,每一個節點的父節點(除了根節點),都可以用當前節點的編號i,表示成(i+1)/3。
每一個節點的葉節點(如果有的話),可以按順序表示成【i*3 - 1】、【i*3】、【i*3+1】。
?
類比二叉堆的 get 操作,讀者需要注意一下這段代碼,并思考一小下為什么,當時我卡了十幾分鐘……(其實還是我菜)
?
如下,是 get 操作中,選取當前節點最小(大)子節點的操作
1 if(next+1<=heap_size && heap[next+1]>heap[next]) { //注意 ,next 最開始 的 值 是 i*3-1 (i 是 now) (其實這是廢話) 2 next++; 3 4 if(next+1<=heap_size && heap[next+1]>heap[next]) next++; 5 } else if(next+2<=heap_size && heap[next+2]>heap[next]) next+=2;(以大頂堆為例)
5.9/2019留言:
這篇文章只是娛樂一下啦,沒什么太大的參考價值的。
?
轉載于:https://www.cnblogs.com/tztqwq/p/10688251.html
總結
- 上一篇: 获取当前周、上一周、下一周日期
- 下一篇: Servlet底层原理、Servlet实