Huffman algorithm [summary]

In a tree, the arrival from any one node to another access node is called a path , the number of edges on the path through which is referred to as the desired length of the path . If the nodes in the tree with weights represent a sense, then arrive at the node from the root node path length multiplied by the weights of the nodes is called with a path length of the right node . All the leaf nodes of the tree with weights and for the path length of the tree with weights and path length . Given n nodes and their weights, as leaf nodes in their right path and configured with the smallest binary one, namely the binary Huffman tree , also referred to as the optimal tree .

Given node Huffman tree may not be unique, the Huffman tree questions machine often needs to be resolved is the path length and the minimum weighted . Recall our well-known method for finding Huffman tree.

1. The set of all nodes into K.

2. If the remaining nodes in the set K is greater than 2, wherein the minimum weight two nodes are removed, they are configured around the same time a new son node, the new node is their common parent node, setting it is right that the two sons and node weights. The father node and into a collection K. Repeat steps 2 or 3.

3. If only one set of K remaining node, the node is the root node of the Huffman tree constructed number of intermediate nodes obtained all configurations (i.e., non-leaf nodes of the Huffman tree) of and the weighted path weight is the Huffman tree and the.

In order to obtain convenient set of weights K minimum of two elements of efficient, we need to use the heap data structure. It can be made of n elements smallest element of complexity O (logn) a. In order to bypass the realization of the heap we use the appropriate standard template standard template library - priority queue.

Example : There are four nodes a, b, c, d, respectively, the weights 7, 5, 2, 4, configured to test this four leaf nodes of the binary tree nodes.

The given values ​​of n weights {w1, w2, ..., wn} binary configuration set F = {T1, T2, ..., Tn}, where each of them only one of Ti binary weighted root node of wi, which left and right sub-tree is empty.

Select two minimum weight tree root node as the left and right subtrees weights a new binary tree configuration in F, and a new set of binary weight value of about root subtree root of the sum.

Delete the two trees in F, while F is added in the new binary tree.

Repeat until F contains only up a tree. (Huffman obtained)

Use statement 

priority_queue<int> Q; 

Save establish a heap elements int Q, but please pay particular attention to the establishment of such a default heap large pile top, ie, the elements we get from the top of the heap for the entire heap largest element. In seeking Huffman tree, we just need to get the smallest element of the heap, so we use the following statement to define a small pile top: (On this point see supplement)

priority_queue<int , vector<int> , greater<int> > Q; 

Example 3.3 Huffman

AC Code

#include<cstdio>
#include<queue>

using namespace std;

priority_queue<int, vector<int>, greater<int> >Q;//建立一个小顶堆

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        while (Q.empty() == false)Q.pop();//清空堆中元素
        for (int i = 1; i <= n; i++)//输入n个叶子结点权值
        {
            int x;
            scanf("%d", &x);
            Q.push(x);//第一步,将n个叶子结点全放入堆中
        }
        int ans = 0;//保存答案
        while (Q.size() > 1)//当堆中元素大于1个
        {
            int a = Q.top();
            Q.pop();
            int b = Q.top();
            Q.pop();//第二步,取出堆中两个最小的元素,设置为同一节点的左右耳子,且双亲节点的权值为他们的和
            ans += a + b;//父节点必为非叶子结点
            Q.push(a + b);//将双亲结点放回堆中
        }
        printf("%d\n", ans);//输出答案
    }
    return 0;
}

补充:关于priority_queue

priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数,priority_queue<Type, Container, Functional>
Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面容器默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。
看例子

#include <iostream>
#include <queue>
using namespace std;
int main(){
    priority_queue<int,vector<int>,less<int> >q;//使用priority_queue<int> q1;一样
    for(int i=0;i<10;i++) 
        q1.push(i);
    while(!q1.empty()){
        cout<<q1.top()<< endl;
        q1.pop();
    }
    return 0;
}

如果要用到小顶堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
例子:

#include <iostream>
#include <queue>
using namespace std;
int main(){
    priority_queue<int,vector<int>,greater<int> >q;
    for(int i=0;i<10;i++) 
        q.push(i);
    while(!q.empty()){
        cout<<q.top()<< endl;
        q.pop();
    }
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/yun-an/p/11070085.html