Huffman algorithm and analysis

Disclaimer: This article is a blogger original article, reproduced, please attach Ming source ^ _ ^ https://blog.csdn.net/cprimesplus/article/details/89893458

Huffman algorithm

solved problem

  ex. in the transmission of messages, different frequencies for each character appears, want to be able to express the message on the premise of its meaning as short as possible, the natural need to make high frequency of appearance of characters occupy as little as possible the number of bits.


thought

  The core Huffman algorithm is a greedy algorithm. Want to achieve the above purpose, it is necessary to make high weight as low as possible the number of bits of character encoding.
  Suppose there are five characters, corresponding weights are: 12345 12345 , according to the greedy strategy, a minimum frequency of every two selected nodes constituting a new tree, then the root node of this tree is added to the original sequence, this sequence is repeated until only a root node, a target value thus obtained is minimal (because the sooner the lower node performs an operation frequency, then the constructed tree, this node layers located on the more lower).

  It is not difficult to write an objective function:
M i n W P L = k = 1 n W k l k Min\quad WPL=\sum_{k=1}^{n}{W_kl_k}
  among them W P L WPL is the weighted path length, W k W_k On behalf of k k Right leaf node weights, l k l_k Representatives from k k leaf node to the root of the distance.


Explanation

  Since the list is always maintained in ascending order, easy to think of using a priority queue to preserve the root of each tree. Examples of the above cited total of five elements, then the initial priority queue there are five root. Then follow the description of the "thinking" part can write.

  Because not previously been the custom priority queue priority, so use them very Shousheng, led me to the wrong tune of four hours, crying ...
  priority queue of two representations:

  1. priority_queue <ElemType> p; this is the default format, default sort order is descending
  2. priority_queue <ElemType, storage containers, comparison rule> p;

2 Description of:
   from small to large: priority_queue <ElemType, vector <ELemType >,greater<ElemType>> p;
   descending: priority_queue <ElemType, vector <ELemType >,less<ElemType> > p;

Custom structure pointer comparison rules:

struct st{
	int weight;
};
struct cmp{
	bool operator()(st *&a,  st *&b)
	{
		return a->weight >= b->weight;
	}
};

Be sure to pay attention to two points! :

  1. From small to capital is greater than the number, write less than descending number
  2. When Huffman algorithm comparative priority queue definitions, write &gt; = &gt;= Number! If the number is greater than the write-only, is added to an existing element of the priority queue, the element will be at the back of the same priority queue element, so that the Huffman algorithm, it is possible subtrees in the improper position, resulting in traverse failure, as shown.

Here Insert Picture Description


Code

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 1024;
struct Huffman{
	int weight;
	struct Huffman *left, *right;

	Huffman(int weight){this->weight = weight;}
};
struct cmp{
	bool operator()(Huffman *&a,  Huffman *&b)
	{
		return a->weight >= b->weight;
	}
};
typedef struct Huffman HuffNode;
typedef priority_queue<HuffNode*,vector<HuffNode*>,cmp> Prior;
void Alloc(HuffNode *&p, int weight)
{
	p = (HuffNode *)malloc(sizeof(HuffNode));
	p->weight = weight;
	p->left = NULL;
	p->right = NULL;
}
HuffNode *createHuffNode(Prior a)
{
	HuffNode *res;
	while(!a.empty())
	{
		HuffNode *root;
		Alloc(root, 0);
		HuffNode *t1 = a.top();a.pop();
		if(a.empty())
		{
			res = t1;
			break;
		}
		HuffNode *t2 = a.top();a.pop();	// t1 <= t2
	 	root->left = t1;
		root->right = t2;
		root->weight = t1->weight + t2->weight;
		a.push(root);
	}
	return res;
}
void InOrderWithoutRecursion(HuffNode *root)
{
	HuffNode *p = root;
	stack<HuffNode*> s;
	while(p || !s.empty())
	{
		while(p)
		{
			s.push(p);
			p = p->left;
		}
		if(!s.empty())
		{
			p = s.top();
			cout<<p->weight<<' ';
			s.pop();
			p = p->right;
		}
	}
}
//int index = 0, value[maxn];
void dfs(HuffNode *root, int *mark, int cnt)
{
	if(!root->left && !root->right)
	{
		cout<<root->weight<<" : ";
		for(int i = 0;i < cnt;i++)
			cout<<mark[i]<<' ';
		cout<<endl;
		return;
	}
	mark[cnt] = 0;
	dfs(root->left, mark, cnt+1);
	mark[cnt] = 1;
	dfs(root->right, mark, cnt+1);
} 
int main()
{
	Prior a;	//存放值 
	const int coeff = 10;
	HuffNode *t[coeff];
	int mark[maxn];
	for(int i = 0;i < coeff;i++)
	{
		Alloc(t[i], i+1);
		a.push(t[i]);
	}
	HuffNode *root = createHuffNode(a);
//	InOrderWithoutRecursion(root);
	dfs(root, mark, 0);
	return 0;
}

Guess you like

Origin blog.csdn.net/cprimesplus/article/details/89893458