Vijos数据结构基础C++实验整理(十)——堆及其应用

该博客介绍了如何使用C++实现最小堆类,包括插入、删除和初始化操作,并给出了样例。同时,展示了计算给定字符串霍夫曼编码长度的方法。代码中包括了最小堆的建堆、插入、删除和排序操作,以及霍夫曼编码长度的计算过程。
摘要由CSDN通过智能技术生成

实验内容:
(一)创建最小堆类。最小堆的存储结构使用 数组。提供操作:插入、删除、初始化。题目第一个操作是建堆操作,接下来是对堆的插入和删除操作,插入和删除都在建好的堆上操作。
(二)计算给定字符串的霍夫曼编码长度

样例:
(一)第一行一个数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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值