堆排序 & 拷贝控制

class maxHeap{
public:
    maxHeap();
    maxHeap(int A[], int n);
    maxHeap(const maxHeap &);             //拷贝控制,声明为public,允许用户进行拷贝
//构造函数也能声明成private,可以提供一个static接口调用构造函数来创建对象
//构造函数或析构声明为private通常是为了限制对象的创建方式。
    maxHeap& operator=(const maxHeap&);    
    int size();
    void setAdds(int n) { adds = n; };
    int top();
    bool push(int);
    bool pop();
    bool empty() { return maxSize == 0; }
    void deleteHeap() { delete this; }    //将析构函数定义为private,使得该类的对象只能通过new创建
private:
    int capacity;  //最大容量
    int maxSize;  //当前已经存储的元素数量
    int adds;    //每次重新分配内存时的增量
    int *A;                  
    void makeMaxHeap();
    void maxHeapFixUp(int);
    void maxHeapFixDown(int);
    ~maxHeap(){ delete []A; }              //需要析构函数的类通常也需要拷贝构造函数以及拷贝赋值运算符
};
maxHeap::maxHeap() : capacity(100), maxSize(0), adds(50), A(new int[capacity]){ }
maxHeap::maxHeap(int N[], int n) : capacity(n + 50), maxSize(n), adds(50), A(new int[capacity]){
    for(int i = 0; i < n; ++i)
        A[i] = N[i];
    makeMaxHeap();
}
maxHeap::maxHeap(const maxHeap &mh) : capacity(mh.capacity), maxSize(mh.maxSize), adds(mh.adds) {
    A = new int[capacity];      //为每个对象重新开辟一块内存
    for(int i = 0; i < maxSize; ++i)
        A[i] = mh.A[i];
}
maxHeap& maxHeap::operator=(const maxHeap &mh){    //拷贝赋值运算符重载需要保证对自身赋值的有效性
    if(capacity < mh.maxSize){
        delete A;
        capacity = mh.maxSize + adds;
        A = new int(capacity);
    }
    maxSize = mh.maxSize;
    for(int i = 0; i < mh.maxSize; ++i)
        A[i] = mh.A[i];
    return *this;
}
int maxHeap::size() { return maxSize; }
int maxHeap::top() {
    if(maxSize == 0){
        cout << "error : There is no elements in the heap !!" << endl;
        return -1;
    }else{
        return A[0];
    }
}
void maxHeap::maxHeapFixDown(int root){    //从上往下调整堆,用于删除堆顶元素
    if(root < 0){
        cout << "error : Invalid input !!" << endl;
        return;
    }
    int j = root * 2 + 1;
    int temp = A[root];
    while(j < maxSize){
        if(j + 1 < maxSize && A[j] < A[j + 1])
            ++j;
        if(temp > A[j])
            break;
        else{
            A[root] = A[j];
            root = j;
            j = root * 2 + 1;
        }
    }
    A[root] = temp;
}
//添加元素时,添加到最后一个位置,并且从下往上调整堆,因为每次调整要保证尽可能少的改变元素
bool maxHeap::push(int elem){    
    if(maxSize < capacity){
        ++maxSize;
    }else{
        if(int *temp = new int[capacity + adds]){   //如果超过最大容量,重新分配一次内存
            for(int i = 0; i < maxSize; ++i)
                temp[i] = A[i];
            ++maxSize;
            delete A;
            A = temp;
        }else{
            cout << "error : Failed to allocate memory !!" << endl;
            return false;
        }
    }
    A[maxSize - 1] = elem;
    maxHeapFixUp(maxSize - 1);
    return true;
}
bool maxHeap::pop(){
    if(maxSize <= 0){
        cout << "error : There is no elements in the heap !!" << endl;
        return false;
    }
    swap(A[0], A[--maxSize]);
    maxHeapFixDown(0);
    return true;
}
void maxHeap::maxHeapFixUp(int child){
    if (child >= maxSize) {
        cout << "error : Invalid input !!" << endl;
        return;
    }
    for(int root = (child - 1) / 2; (root >= 0 && child != 0) && A[root] < A[child]; child = root, root = (child - 1) / 2)
        swap(A[root], A[child]);
}
void maxHeap::makeMaxHeap(){
    for(int root = maxSize / 2 - 1; root >= 0; --root)  // root初始值为最后一个节点的双亲节点,即(maxSize-2)/2
        maxHeapFixDown(root);
}
int main(){
    int A[10]{3,5,6,7,9,1,34,67,12,17};
    maxHeap *p = new maxHeap(A, 10);  //只能通过new创建对象
    maxHeap *q = new maxHeap(*p);    //合法,拷贝构造函数是public的
    p->push(56);
    p->push(-3);
    int size = p->size();
    for(int i = 0; i < size; ++i){
        cout << p->top() << " ";
        p->pop();
    }
    cout << endl;
    p->deleteHeap();        //通过public接口调用析构函数手动释放内存
    q->deleteHeap();
    return 0;
}
 
 

 

posted on 2014-12-13 17:29  远近闻名的学渣  阅读(183)  评论(0)    收藏  举报

导航