面向对象的堆实现

自己写的小根堆类
发现一个问题:堆并没有不允许出现重复元素这个性质,之前一直有错误的印象
当类中含有vector数据成员时,构造函数怎么写?答案是不写,交给vector的默认构造函数处理.

#include <iostream>
#include <vector>

using namespace std;

template<typename T>
class MinHeap{
      
      //int* heap; //使用指针变量来指向一片存储区域,是否是一个不好的习惯? 
    vector<T> heap;
      
    void siftDown(int root, int bound, vector<T>& a) {
        int l_idx;
        int r_idx;
        int next;
        T temp;
        while (2*root+1 <= bound) {
            l_idx = 2 * root + 1;
            r_idx = 2 * root + 2;
            if (r_idx <= bound) next = a[l_idx]<a[r_idx]? l_idx: r_idx;
            else next = l_idx;
        
            if (a[root] > a[next]) {
                temp = a[root];
                a[root] = a[next];
                a[next] = temp;
                root = next;
            }
            else return;
        }
    }
    
    void siftUp(int start) { //start是末尾点 
         if ((start-1)/2 < 0) return;
         else {
             int root = (start-1)/2;
             T temp;
             while (start > 0) {
                 if (heap[root] > heap[start]) {
                     temp = heap[root];
                     heap[root] = heap[start];
                     heap[start] = temp;
                     start = root; //更新start 
                     root = (start - 1) / 2; //更新root 
                     //cout << "root=" << root << endl;
                     //cout << "start=" << start << endl;
                 }
                 else return;
             }
         }
    }

public:

    MinHeap(int left, int right, T a[]){
        for (int i = left; i <= right; ++i)
            heap.push_back(a[i]);
        createMinHeap();
    }

    void show() {
        for (int i = 0; i < size(); ++i)
            cout << heap[i] << " ";
        cout << endl;
    }
        
    void createMinHeap() {
        cout << "orin:";
        show(); 
        for (int i = (heap.size()-2)/2; i >= 0; --i) {
            cout << "i=" << i << ", ";
            siftDown(i, heap.size()-1, heap);
            cout << "after one siftDown:" ;
            show();
        } 
        cout << "minHeap:"; 
        show();
    }
    
    void Insert(T val) {
        heap.push_back(val);
        siftUp(size()-1);
        show();
    }
             

    bool Remove(T& elem) {
        if (heap.size() <= 0) return false;
        elem = heap[0];
        heap[0] = heap[heap.size()-1]; 
        heap.pop_back();
        siftDown(0, heap.size()-1, heap);
        //cout << "after remove:"; 
        //show();
        //cout << "elem=" << elem << endl;
        return true;
    }
    
    int size() {
        return heap.size();
    }
};

int main() {
    int a[10] = {0, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    MinHeap<int> h(0, 9, a);
    //h.createMinHeap();
    h.Insert(-1);
    h.Insert(7); //重复数,
    h.Insert(12);
    int b[12];
    for (int i = 0; i < 12; ++i) 
        h.Remove(b[i]);
    
    cout << "b:"; 
    for (int i = 0; i < 12; ++i)
        cout << b[i] << " ";
    cout << endl;
    
    system("pause");
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值