數據結構--大小根堆模板類

1、大/小根堆成員屬性:構造函數第二個參數決定大根堆與小根堆

能夠利用根堆求解大小位置的數組中前i大或者前i小的元素,也能夠將其進行按大小排序。ios

原理與特色:利用徹底二叉樹的父子結點在線性表中的索引關係,較爲高效的利用空間去實現樹形結構,並達到相關要求。這裏以索引值 1 爲堆頂元素索引做爲展開。數組

  爲了更好的去使用大小根堆,採用標誌參數:max_heap和min_heap來實現大小根堆的切換,更好的下降了代碼量,同時也能儘可能保持功能的完整與執行的高效。函數

  (不完善的地方:應該改進存放容器方式,避免容器的再哈希產生沒必要要的時間開銷,能夠在構造對象的時候就肯定容器的大小)測試

 1 #include<iostream>
 2 #include<stdlib.h>
 3 #include<vector>
 4 #include<ctime> 
 5 #define Size long long
 6 using namespace std;
 7 template<typename P>
 8 class heap{
 9     private:
10         Size heap_size;//容量限制 
11         Size heap_count;//數據計數 
12         vector<P> heap_elem;//堆容器 
13         int maxmin_heap;//選擇大\小根堆 
14         
15         void Up_adjust(int now);//上浮調整 
16         void Down_adjust(P &top, int now);//下沉調整 
17     public:
18         enum{max_heap=1, min_heap=-1};
19         heap(Size s, int m=max_heap)://構造堆 
20             heap_size(s){
21             heap_count=0;
22             heap_elem.push_back(-999);
23             maxmin_heap=m;//default max_heap
24         };
25         P getTop(){//彈獲取堆頂元素 
26             if(heap_count>0)return heap_elem[1];
27             return heap_elem[0]*maxmin_heap;
28         } 
29         bool empty(){//判斷堆空 
30             if(heap_count==0)return true;
31             return false;
32         }
33         void push(P x);//送元素入堆 
34         P pop();//堆頂元素彈出 
35         void Delete(int i);//刪除第i個元素 
36         void data();//打印堆
37 }; 

2、大小根堆成員函數:

1.插入元素:將新元素放入堆底,執行上浮調整,使其合理this

1 template<typename P>
2 void heap<P>::push(P x){
3     ++heap_count;
4     heap_elem.push_back(x*maxmin_heap);
5     int now=heap_count;
6     Up_adjust(now);
7     if(heap_count>heap_size-1)
8         heap_count--;
9 }

2.彈出元素:spa

template<typename P>
P heap<P>::pop(){
    this->Delete(0);
    return getTop()*maxmin_heap;
}

3.刪除元素:code

用堆底元素替換,並經過下沉調整,使其合理對象

 1 template<typename P>
 2 void heap<P>::Delete(int i){
 3     if(i>heap_count) return;
 4     cout << "delete heap["<< i <<"]: " << heap_elem[i]*maxmin_heap << endl;
 5     if(i==heap_count){
 6         heap_count--;
 7         return ;}
 8     Down_adjust(heap_elem[heap_count],i);
 9     heap_count--;
10 }

4.上浮調整:blog

1 template<typename P>
2 void heap<P>::Up_adjust(int now){
3     while(now>1 && heap_elem[now]>heap_elem[now/2]){
4         std::swap(heap_elem[now], heap_elem[now/2]);
5         now=now/2;
6     }
7 }

5.下沉調整:排序

 1 template<typename P>
 2 void heap<P>::Down_adjust(P &top, int now){
 3     heap_elem[now]=top;
 4     int next1,next2;
 5     while(now*2<=heap_count){
 6         if(now*2+1>heap_count){
 7             next1=next2=now*2;
 8         }
 9         else{
10             next1 = heap_elem[now*2]>heap_elem[now*2+1] ? now*2 : now*2+1;
11             next2 = heap_elem[now*2]<heap_elem[now*2+1] ? now*2 : now*2+1;    
12         } 
13         if(heap_elem[next1]>heap_elem[now]){
14             swap(heap_elem[next1],heap_elem[now]);
15             now = next1;
16         }
17         else if(heap_elem[next2]>heap_elem[now]){
18             swap(heap_elem[next2],heap_elem[now]);
19             now = next2;
20         }
21         else{
22             break;
23         }
24     }    
25 }

6.數據打印:

1 template<typename P>
2 void heap<P>::data(){
3     typename std::vector<P>::iterator itr=heap_elem.begin()+1;
4     cout << "heap[]: ";
5     for(int i=0;i<heap_count && i<heap_size;++i){
6         cout << *(itr+i)*maxmin_heap << ' ';
7     }
8     cout << endl;
9 }

3、代碼測試:以小根堆爲例

能夠註釋掉標準輸出語句,來減小執行操做的時間消耗,能更好測試大量數據插入、刪除的實行時間。

 1 int main(){
 2     heap<int> h(20,heap<int>::min_heap);
 3     int x;
 4     srand(time(NULL));
 5     for(int i=0;i < 20;++i){
 6         x = rand()%1000;
 7         h.push(x);
 8         //h.data();
 9     }
10     h.data();
11     h.Delete(4);
12     while(!h.empty()){
13         h.pop();
14     }
15     cout << endl;
16     return 0;
17 }

相關文章
相關標籤/搜索