内容
创建 最小堆类。最小堆的存储结构使用 数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。
格式
输入
第一行一个数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;
}