Vj数据结构实验10(一)

内容

创建 最小堆类。最小堆的存储结构使用 数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。

格式

输入

第一行一个数n(n<=5000),代表堆的大小。第二行n个数,代表堆的各个元素。
第三行一个数m (m<=1000),代表接下来共m个操作。接下来m行,分别代表各个操作。下面是各个操作的格式:

  • 插入操作:1 num
  • 删除操作:2
  • 排序操作:第一行两个数3和n,3代表是排序操作,n代表待排序的数的数目,接下来一行n个数是待排序数

保证排序操作只出现一次且一定是最后一个操作。

输出

第一行建堆操作输出建好堆后堆顶的元素。
接下来m个操作,若是插入和删除操作,每行输出执行操作后堆顶的元素的值;若是排序操作,输出一行按升序排序好的结果,每个元素间用空格分隔。

样例

输入

10
-225580 113195 -257251 384948 -83524 331745 179545 293165 125998 376875
10
1 -232502
1 -359833
1 95123
2
2
2
1 223971
1 -118735
1 -278843
3 10
-96567 37188 -142422 166589 -169599 245575 -369710 423015 -243107 -108789

输出

-257251
-257251
-359833
-359833
-257251
-232502
-225580
-225580
-225580
-278843
-369710 -243107 -169599 -142422 -108789 -96567 37188 166589 245575 423015 

Limitation

1s, 64MB for each test case.

#include <iostream>
using namespace std;
template<class T>
class minHeap{
    public:
        minHeap(int n = 10);
        // ~minHeap(){};
        void push(const T& theElement); // 插入
        void pop(); // 删除
        void sorted(T a[], int n); //排序
        void pop2(); // 排序时删除
        void initialized(T *theHeap, int theSize); // 排序时初始化
        void initialize(T *theHeap, int theSize); // 初始化
        // 增加长度函数
        void changeLengthld(T *&a, int oldLength, int newlength){
            T *temp = new T[newlength];
            int number = min(oldLength, newlength);
            copy(a, a + number, temp);
            delete[]a;
            a = temp;
        }
        void push2(const T& theElement);
        void top(){
            cout << heap[1] << endl;
        }
    private:
        T *heap; // 数组
        int arrayLength; // 数组长度
        int heapSize; // 堆中元素个数
};
// 排序插入
template<class T>
void minHeap<T>::push2(const T& theElement){// 把元素theELement加入堆
    // 必要时增加数组长度
    if(heapSize == arrayLength - 1){
        changeLengthld(heap, arrayLength, 2*arrayLength);
        arrayLength *= 2;
    }
    // 为元素theElement寻找插入位置
    // currentNode从新叶子向上移动
    int currentNode = ++heapSize;
    while(currentNode != 1 && heap[currentNode / 2] > theElement){
        // 不能把元素theElement插入在heap[currentNode]
        heap[currentNode] = heap[currentNode / 2];  // 把元素向上移
        currentNode /= 2; // 移向根节点
    }
    heap[currentNode] = theElement;
}

// 插入
template<class T>
void minHeap<T>::push(const T& theElement){// 把元素theELement加入堆
    // 必要时增加数组长度
    if(heapSize == arrayLength - 1){
        changeLengthld(heap, arrayLength, 2*arrayLength);
        arrayLength *= 2;
    }
    // 为元素theElement寻找插入位置
    // currentNode从新叶子向上移动
    int currentNode = ++heapSize;
    while(currentNode != 1 && heap[currentNode / 2] > theElement){
        // 不能把元素theElement插入在heap[currentNode]
        heap[currentNode] = heap[currentNode / 2];  // 把元素向上移
        currentNode /= 2; // 移向根节点
    }
    heap[currentNode] = theElement;
    cout << heap[1] << endl;
}

// 删除
template<class T>
void minHeap<T>::pop(){
    heap[1].~T(); // 删除最小元素
    T lastElement = heap[heapSize--]; // 删除最后一个元素,然后重新建堆
    // 从跟开始,为最后一个元素找位置
    int currentNode = 1, child = 2;
    while(child <= heapSize){
        if(child < heapSize && heap[child] > heap[child+1]) // 依次进行比较
            child++;
        if(lastElement <= heap[child]) // 如果最后一个元素小于child,直接将lastElement放在根上
            break;
        heap[currentNode] = heap[child]; // 进行继续向孩子比较
        currentNode = child;
        child *=2;
    }
    heap[currentNode] = lastElement; // 为lastElement找到一个位置
    cout << heap[1] << endl;
}

// 初始化
template<class T>
void minHeap<T>::initialize(T* theHeap, int theSize){
    // 在数组theHeap[1:theSize]中建立小根堆
    delete []heap;
    heap = theHeap;
    heapSize = theSize;
    // 堆化
    for(int root = heapSize / 2; root >= 1; root--){
        T rootElement = heap[root]; // 从叶节点的根开始
        int child = 2 * root; // 叶子
        while(child <= heapSize){ // 选择较小的孩子
            if(child < heapSize && heap[child] > heap[child + 1])
                child++;
            if(rootElement <= heap[child]) // 根小于孩子则不用换
                break;
            heap[child/2] = heap[child]; // 根于孩子进行交换
            child *= 2;
        }
        heap[child / 2] = rootElement;
    }
    cout << heap[1] << endl;
}

// 排序初始化
template<class T>
void minHeap<T>::initialized(T* theHeap, int theSize){
    // 在数组theHeap[1:theSize]中建立小根堆
    delete []heap;
    heap = theHeap;
    heapSize = theSize;
    // 堆化
    for(int root = heapSize / 2; root >= 1; root--){
        T rootElement = heap[root];
        int child = 2 * root;
        while(child <= heapSize){
            if(child < heapSize && heap[child] > heap[child + 1])
                child++;
            if(rootElement <= heap[child])
                break;
            heap[child/2] = heap[child];
            child *= 2;
        }
        heap[child / 2] = rootElement;
    }
    // cout << heap[1] << endl;
}
// 构造函数
template<class T>
minHeap<T>::minHeap(int n){
    arrayLength = 10;
    heapSize = 0;
    heap = new T[n];
}

// 排序
template<class T>
void minHeap<T>::sorted(T a[],int n){
    initialized(a, n);
    for(int i = n; i>= 1; i--){
        cout << heap[1] << " ";
        pop2();
    }
    cout << endl;
}
// 排序删除
template<class T>
void minHeap<T>::pop2(){
    heap[1].~T(); // 删除最小元素
    T lastElement = heap[heapSize--]; // 删除最后一个元素,然后重新建堆
    // 从跟开始,为最后一个元素找位置
    int currentNode = 1, child = 2;
    while(child <= heapSize){
        if(child < heapSize && heap[child] > heap[child+1]) // 依次进行比较
            child++;
        if(lastElement <= heap[child]) // 如果最后一个元素小于child,直接将lastElement放在根上
            break;
        heap[currentNode] = heap[child]; // 进行继续向孩子比较
        currentNode = child;
        child *=2;
    }
    heap[currentNode] = lastElement; // 为lastElement找到一个位置
}
int main(){
    int n;
    cin >> n;
    int a[n+1];
    a[0] = 0;
    minHeap<int> B(10);
    for(int i = 1; i <= n; i++){
        cin >> a[i];
        B.push2(a[i]);
    }
    B.top();
    // B.initialize(a, n);
    int m;
    cin >> m;
    for(int j = 0; j < m; j++){
        int d;
        cin >> d;
        switch(d){
            case 1: {int x; cin >> x; B.push(x);}
                break;
            case 2: B.pop();
                break;
            case 3: {int g; cin >> g; int y[g+1];for(int i = 1; i <= g; i++)cin >> y[i];y[0]=0;
                    B.sorted(y, g);}
                break;
        }
    }
    
    return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值