C++实现堆、最大堆、最小堆 -- 堆排序插入删除操作

堆是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于(或不小于)其左孩子和右孩子节点的值。
最大堆和最小堆是 二叉堆 的两种形式。
最大堆:根结点的键值是所有堆结点键值中最大者。
最小堆:根结点的键值是所有堆结点键值中最小者。
而最大-最小堆集结了最大堆和最小堆的优点,这也是其名字的由来。
最大-最小堆是最大层和最小层交替出现的 二叉树 ,即最大层结点的儿子属于最小层,最小层结点的儿子属于最大层。
以最大(小)层结点为根结点的子树保有最大(小)堆性质:根结点的键值为该子树结点键值中最大(小)项。 
                                                                                                                                                                                              
一:堆
  我们构建一个堆类,用最大堆和最小堆来继承他。

#ifndef _HEAP_H  
#define _HEAP_H  
  
#include <iostream>  
using namespace std;  
  
enum{DEFAULT_SIZE = 10};  
  
template <typename T>  
class Heap{  
public:  
    Heap() = default;  
    virtual ~Heap() = default;  
public:   
    virtual void show_heap()const = 0;  
    virtual bool insert_heap(const T&) = 0;  
    virtual bool remove_heap(T &) = 0;  
};  
  
//public interface  
  
#endif   /*Heap.h*/  

二:最大堆

  下面是最大堆的实现:

#ifndef _MAXHEAP_H  
#define _MAXHEAP_H  
  
#include <iostream>  
  
#include "Heap.h"  
  
template <typename T>  
class MaxHeap : public Heap<T>{  
public:  
    MaxHeap(int);  
    MaxHeap(const T [], const int);  
    ~MaxHeap();  
public:  
    bool insert_heap(const T&);  
    bool remove_heap(T &);  
  
    void show_heap()const;  
protected:  
    void sift_down(int, int);  
    void sift_up(int);  
private:  
    T *heap;  
    int size;  
    int capacity;  
};  
  
//public interface  
  
template <typename T>  
MaxHeap<T>::MaxHeap(int sz = DEFAULT_SIZE)  
{  
    capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;  
    heap = new T[capacity];  
    assert(heap != NULL);  
    size = 0;  
}  
  
template <typename T>  
MaxHeap<T>::MaxHeap(const T arr[], const int arrSize)  
{  
    capacity = arrSize > DEFAULT_SIZE ? arrSize : DEFAULT_SIZE;  
    heap = new T[capacity];  
    assert(heap != NULL);  
    size = arrSize;  
  
    for(int i=0; i<size; ++i)  
        heap[i] = arr[i];  
      
    int curPos = size/2 - 1;  
    while(curPos >= 0){  
        sift_down(curPos, size-1);  
        --curPos;  
    }  
      
}  
  
template <typename T>  
MaxHeap<T>::~MaxHeap()  
{  
    delete []heap;  
    heap = NULL;  
    capacity = size = 0;  
}  
  
template <typename T>  
bool MaxHeap<T>::insert_heap(const T& val)  
{  
    if(size >= capacity)  
        return false;  
      
    heap[size] = val;  
    sift_up(size);  
    ++size;  
    return true;  
}  
  
template <typename T>  
bool MaxHeap<T>::remove_heap(T &val)  
{  
    if(size <= 0)  
        return false;  
      
    val = heap[0];  
    heap[0] = heap[size-1];  
    --size;  
    sift_down(0, size-1);  
    return true;  
}  
  
template <typename T>  
void MaxHeap<T>::show_heap()const  
{  
    for(int i=0; i<size; ++i)  
        std::cout << heap[i] << " ";  
    std::cout << std::endl;  
}  
  
//protected interface  
  
template <typename T>  
void MaxHeap<T>::sift_down(int start, int end)  
{  
    int i = start;  
    int j = i*2 + 1;  
  
    T tmp = heap[i];  
    while(j <= end){  
        if(j+1 <= end && heap[j] < heap[j+1])  
            ++j;  
        if(tmp < heap[j])  
            heap[i] = heap[j];  
        else  
            break;  
  
        i = j;  
        j = j*2 + 1;  
    }  
    heap[i] = tmp;  
}  
  
template <typename T>  
void MaxHeap<T>::sift_up(int start)  
{  
    int j = start;  
    int i = (start-1) / 2;  
  
    T tmp = heap[j];  
    while(j > 0){  
        if(tmp < heap[i])  
            break;  
        else  
            heap[j] = heap[i];  
          
        j = i;  
        i = (i-1) / 2;  
    }  
    heap[j] = tmp;  
}  
  
#endif   /*MaxHeap.h*/  
三:最小堆
  下面是最小堆的实现:
#ifndef _MINHEAP_H  
#define _MINHEAP_H  
  
#include <assert.h>  
  
#include "Heap.h"  
  
template <typename T>  
class MinHeap : public Heap<T>{  
public:  
    MinHeap(int);  
    MinHeap(const T [], const int );  
    ~MinHeap();  
public:  
    bool insert_heap(const T&);  
    bool remove_heap(T &);  
      
    void show_heap()const;  
protected:  
    void sift_down(int, int);  
    void sift_up(int);  
private:  
    T* heap;  
    int size;  
    int capacity;  
};  
  
//interface  
  
template <typename T>  
MinHeap<T>::MinHeap(int sz = DEFAULT_SIZE)  
{  
    capacity = sz > DEFAULT_SIZE ? sz : DEFAULT_SIZE;  
    heap = new T[capacity];  
    assert(heap != NULL);  
    size = 0;  
}  
  
template <typename T>  
MinHeap<T>::MinHeap(const T arr[], const int arrSize)  
{  
    capacity = arrSize > DEFAULT_SIZE ? arrSize : DEFAULT_SIZE;  
    heap = new T[capacity];  
    assert(heap != NULL);  
    size = arrSize;  
  
    for(int i=0; i<arrSize; ++i)  
        heap[i] = arr[i];  
      
    int curPos = arrSize/2 - 1;  
    while(curPos >= 0){  
        sift_down(curPos, arrSize-1);  
        --curPos;  
    }  
}  
  
template <typename T>  
MinHeap<T>::~MinHeap()  
{  
    delete []heap;  
    heap = NULL;  
    capacity = size = 0;  
}  
  
template <typename T>  
bool MinHeap<T>::insert_heap(const T& val)  
{  
    if(size >= capacity)  
        return false;  
      
    heap[size] = val;  
    sift_up(size);  
    ++size;  
    return true;  
}  
  
template <typename T>  
bool MinHeap<T>::remove_heap(T& val)  
{  
    if(size <= 0)  
        return false;  
      
    val = heap[0];  
    heap[0] = heap[size-1];  
    --size;  
    sift_down(0, size-1);  
    return true;  
}  
  
template <typename T>  
void MinHeap<T>::show_heap()const  
{  
    for(int i=0; i<size; ++i)  
        std::cout << heap[i] << " ";  
    std::cout << std::endl;  
}  
  
//protected interface  
  
template <typename T>  
void MinHeap<T>::sift_down(int start, int end)  
{  
    int i = start;  
    int j = start*2 + 1;  
  
    T tmp = heap[i];  
    while(j <= end){  
        if(j+1 < end && heap[j] > heap[j+1])  
            ++j;  
        if(tmp < heap[j])  
            break;  
        else  
            heap[i] = heap[j];  
          
        i = j;  
        j = j*2 + 1;  
    }  
    heap[i] = tmp;  
}  
  
template <typename T>  
void MinHeap<T>::sift_up(int start)  
{  
    int j = start;  
    int i = (start-1) / 2;  
  
    T tmp = heap[j];  
    while(j > 0){  
        if(tmp > heap[i])  
            break;  
        else  
            heap[j] = heap[i];  
        j = i;  
        i = (i-1) / 2;  
    }  
    heap[j] = tmp;  
}  
  
#endif  

四:测试如下:

#include "MinHeap.h"  
#include "MaxHeap.h"  
#include <iostream>  
using namespace std;  
  
int main()  
{  
    int array[] = {23, 9, 34, 2, 56, 89, 35, 54};  
      
    cout << "***************************MinHeap***************************" << endl;  
    MinHeap<int> min_heap(array, sizeof(array)/sizeof(int));  
      
    min_heap.show_heap();  
    min_heap.insert_heap(1);  
    min_heap.show_heap();  
    for(int i=0; i<9; ++i){  
        int val;  
        min_heap.remove_heap(val);  
        cout << val << " ";  
    }  
    cout << endl;  
      
    MaxHeap<int> max_heap(array, sizeof(array)/sizeof(int));  
    cout << "***************************MaxHeap**************************" << endl;   
    max_heap.show_heap();  
    max_heap.insert_heap(99);  
    max_heap.show_heap();  
    for(int i=0; i<9; ++i){  
        int val;  
        max_heap.remove_heap(val);  
        cout << val << " ";  
    }  
    cout << endl;  
      
    return 0;  
}  
结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值