实验内容:
(一)创建最小堆类。最小堆的存储结构使用 数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。
(二)计算给定字符串的霍夫曼编码长度
样例:
(一)第一行一个数n(n<=5000),代表堆的大小。第二行n个数,代表堆的各个元素。
第三行一个数m (m<=1000),代表接下来共m个操作。接下来m行,分别代表各个操作。下面是各个操作的格式:
• 插入操作:1 num
• 删除操作:2
• 排序操作:第一行两个数3和n,3代表是排序操作,n代表待排序的数的数目,接下来一行n个数是待排序数
保证排序操作只出现一次且一定是最后一个操作。
第一行建堆操作输出建好堆后堆顶的元素。
接下来m个操作,若是插入和删除操作,每行输出执行操作后堆顶的元素的值;若是排序操作,输出一行按升序排序好的结果,每个元素间用空格分隔。
(二)输入:一串小写字母组成的字符串(不超过1000000)。
输出:输出这个字符串通过Huffman编码后的长度。
代码实现(从上到下分别为题目一、二的C++代码):
#include<iostream>
#include <sstream>
#include <algorithm>
using namespace std;
template<class T>
void changeLength1D(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 maxPriorityQueue
{
public:
virtual ~maxPriorityQueue() {}
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual const T& top() = 0;
virtual void pop() = 0;
virtual void push(const T& theElement) = 0;
};
template<class T>
class maxHeap : public maxPriorityQueue<T>
{
public:
maxHeap(int initialCapacity = 10);
~maxHeap() { delete[] heap; }
bool empty() const { return heapSize == 0; }
int size() const
{
return heapSize;
}
const T& top()
{
return heap[1];
}
void pop();
void push(const T&);
void initialize(T*, int);
void deactivateArray()
{
heap = NULL; arrayLength = heapSize = 0;
}
void output(ostream& out) const;
private:
int heapSize;
int arrayLength;
T* heap;
};
template<class T>
maxHeap<T>::maxHeap(int initialCapacity)
{
arrayLength = initialCapacity + 1;
heap = new T[arrayLength];
heapSize = 0;
}
template<class T>
void maxHeap<T>::push(const T& theElement)
{
if (heapSize == arrayLength - 1)
{
changeLength1D(heap, arrayLength, 2 * arrayLength);
arrayLength *= 2;
}
int currentNode = ++heapSize;
while (currentNode != 1 && heap[currentNode / 2] > theElement)
{
heap[currentNode] = heap[currentNode / 2];
currentNode /= 2;
}
heap[currentNode] = theElement;
}
template<class T>
void maxHeap<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])
break;
heap[currentNode] = heap[child];
currentNode = child;
child *= 2;
}
heap[currentNode] = lastElement;
}
template<class T>
void maxHeap<T>::initialize(T* theHeap, int 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;
}
}
int main(void)
{
int m, n;
cin >> n;
maxHeap<int> minheap(n);
for (int i = 0; i < n; i++) {
int num;
cin >> num;
minheap.push(num);
}
cout << minheap.top() << endl;
cin >> m;
for (int i = 0; i < m; i++) {
int op, num;
cin >> op;
if (op == 1){
cin >> num;
minheap.push(num);
cout << minheap.top() << endl;
}
if (op == 2) {
minheap.pop();
cout << minheap.top() << endl;
}
if (op == 3) {
int p;
cin >> p;
maxHeap<int> minheap1(p);
for (int i = 0; i < p; i++) {
int number;
cin >> number;
minheap1.push(number);
}
for (int i = 0; i < p; i++) {
cout << minheap1.top() << " ";
minheap1.pop();
}
}
}
return 0;
}
#include <iostream>
#include <string>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
string str;
map<char, int> MAP;
priority_queue<int, vector<int>, greater<int> >PQ;
int main() {
getline(cin, str);
int len = str.length();
for (int i = 0; i < len; i++) {
if (MAP.find(str[i]) == MAP.end()) {
MAP[str[i]] = 1;
}
else {
MAP[str[i]]++;
}
}
for (map<char, int>::iterator it = MAP.begin(); it != MAP.end(); it++) {
PQ.push(it->second);
}
int flag = 0;
while (PQ.size() != 1) {
int a, b, trans;
a = PQ.top();
PQ.pop();
b = PQ.top();
PQ.pop();
trans = a + b;
flag += trans;
PQ.push(trans);
}
cout << flag << endl;
return 0;
}