内容
创建 最小堆类。最小堆的存储结构使用 数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。
格式
输入
第一行一个数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>
// 增加长度函数
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;
}
template <class T>
class minHeap{
public:
minHeap(int n = 10);
// ~minHeap(){};
void sorted(T a[], int n); //排序
void pop(); // 排序时删除
void initialized(T *theHeap, int theSize); // 排序时初始化
void push(const T& theElement);
void top(){
cout << heap[1] << endl;
}
private:
T *heap; // 数组
int arrayLength; // 数组长度
int heapSize; // 堆中元素个数
};
// 排序插入
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;
}
// 排序初始化
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;
}
}
// 构造函数
template<class T>
minHeap<T>::minHeap(int n){
arrayLength = 10;
heapSize = 0;
heap = new T[n];
}
// 排序
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找到一个位置
}
template<class T>
void minHeap<T>::sorted(T a[],int n){
initialized(a, n);
for(int i = n; i>= 1; i--){
cout << heap[1] << " ";
pop();
}
cout << endl;
}
// 排序删除
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.push(a[i]);
}
B.top();
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);B.top();}
break;
case 2:{ B.pop();B.top();}
break;
case 3: {int num;
cin >> num; int y[num+1];
for(int i = 1; i <= num; i++)cin >> y[i];
y[0]=0;
B.sorted(y, num);}
break;
}
}
return 0;
}
格式
输入
一串小写字母组成的字符串(不超过1000000)。
输出
输出这个字符串通过Huffman编码后的长度。
样例
输入
abcdabcaba
输出
19
限制
1s, 1024KiB for each test case.
提示
样例中,'a' 出现了4次,'b' 出现了3次,'c' 出现了2次,'d' 出现了1次
编码为: 'a' : 0 'b' : 10 'c' : 110 'd' : 111
#include <iostream>
using namespace std;
template <class T>
// 定义哈夫曼节点
struct Node {
T weight;
Node* leftchild, * rightchild;
Node() {}
Node(T w) {
weight = w;
rightchild = leftchild = NULL;
}
Node(T w, Node* r,Node* l) {
weight = w;
rightchild = r;
leftchild = l;
}
};
template <class T>
class huffmanTree {
public:
huffmanTree(int* a, int n); // 构造函数
~huffmanTree(){delete []heap;}; // 析构函数
void initialize(); // 初始化
Node<T>* top() { // 返回小根堆的堆顶元素
return heap[1];
}
void push(Node<T>* h); // 插入
void pop(); // 删除
void makeTree(); // 建造哈夫曼树
T cal(Node<T>* t, int n);// 进行计算长度
private:
Node<T>** heap; // 定义一个指针小根堆
int heapSize; // 小根堆的长度
};
// 构造函数
template <class T>
huffmanTree<T>::huffmanTree(int* a, int n) {
heapSize = n; // 定义长度
heap = new Node<T> * [27];
for (int i = 1; i <= n; i++) { // 为heap[i]赋值(有值的)
heap[i] = new Node<T>(a[i - 1]);
}
}
// 小根堆初始化
template <class T>
void huffmanTree<T>::initialize() {
for (int root = heapSize / 2; root >= 1; root--) {
Node<T>* theElement = heap[root];
int child = root * 2;
while (child <= heapSize) {
if (child<heapSize && heap[child]->weight>heap[child + 1]->weight) {
child++;
}
if (theElement->weight <= heap[child]->weight) {
break;
}
heap[child / 2] = heap[child];
child *= 2;
}
heap[child / 2] = theElement;
}
}
// 小根堆插入
template <class T>
void huffmanTree<T>::push(Node<T>* h) {
int now = ++heapSize;
while (now != 1 && heap[now / 2]->weight > h->weight) {
heap[now] = heap[now / 2];
now /= 2;
}
heap[now] = h;
}
// 小根堆删除
template <class T>
void huffmanTree<T>::pop() {
Node<T>* theElement = heap[heapSize--];
int now = 1;
int child = 2;
while (child <= heapSize) {
if (child<heapSize && heap[child]->weight>heap[child + 1]->weight) {
child++;
}
if (theElement->weight <= heap[child]->weight) {
break;
}
heap[now] = heap[child];
now = child;
child *= 2;
}
heap[now] = theElement;
}
// 建造哈夫曼树
template <class T>
void huffmanTree<T>::makeTree() { // 取小根堆前两个节点进行合并,并将合并之后的结果插入小根堆中
while (heapSize != 1) {
Node<T>* x = top();
pop();
Node<T>* y = top();
pop();
Node<T>* z = new Node<T>(x->weight + y->weight, x, y);
push(z);
}
}
// 计算长度
template <class T>
T huffmanTree<T>::cal(Node<T>* t, int n) {
int sum = 0;
if (t != NULL) {
if (t->rightchild == NULL && t->leftchild == NULL) { // 判断是否为子节点,是子节点则计算长度
sum += n * t->weight; // 长度等于weight * 层数(根为0层)
}
// 递归使用进行左右孩子中的计算
sum += cal(t->leftchild, n + 1);
sum += cal(t->rightchild, n + 1);
}
return sum;
}
int main() {
string str;
cin >> str;
int num = 0, flag = 0;
int* a = new int[26]; // 初始化a
for (int i = 0; i < 26; i++) {
a[i] = 0;
}
for (int i = 0; i < str.length(); i++) {
a[(int)str[i] - 'a']++;
if (a[str[i] - 'a'] == 1) {
num++; // 字母中次数大于等于1的个数
}
}
int* b = new int[num]; // 出现的字母储存在b中
for (int i = 0; i < 26; i++) {
if (a[i] != 0) {
b[flag] = a[i];
flag++;
}
}
huffmanTree<int> c(b, flag);
c.initialize();
c.makeTree();
cout << c.cal(c.top(), 0) << endl;
return 0;
}
标签:Node,10,weight,int,void,heap,child,数据结构,山东大学
From: https://www.cnblogs.com/lyz103/p/17355579.html