[算法导论读书笔记]huffman编码

        huffman编码,大家都知道,不再过介绍。下面的程序只做练习,输入任意长度的字符,自动用根据字符的出现次数进行编码,可以看到,出现次数越多的字符,编码长度越短,这也是huffman编码的特点。需要注意的是,由于有些字符是不可打印的,或者打印出现看得不明显的,输出时输出的是其ASSIC码值。在linux下按ctrl+d结束输入,windows下么,我也不知道,自己google吧。

#include <iostream>
#include <vector>
#include <string.h>
#include <stack>
#include <stdio.h>
using namespace std;
const int MAXN = 1000;// 队列的大小 
const int ASSICN = 128;// assic为1——127的字符
const int INFINITY = 99999;

vector<int> v;
struct node
{
	int ch;
	double cost;
	struct node *lchild;
	struct node *rchild;
	node(int ch = 0, double cost = 0.0 )
	{
		ch = ch;
		cost = cost;
		lchild = NULL;
		rchild = NULL;
	}
	bool operator < (const node &rhs) const
	{
		return cost < rhs.cost;
	}
	void operator = (const  node &rhs) 
	{
		ch = rhs.ch;
		cost = rhs.cost;

	}
};

typedef node* pnode;
pnode Q[MAXN]; // queue
int k = 0;// No.of node in  the queue

pnode extractMin()
{
	// extracte the node which has a least cost

	int i = 0;
	pnode temp;
	int min = INFINITY;
	int mini = 0;
	for( i = 0; i < k; i++)
	{
		if( Q[i] != NULL )
		{
			if( Q[i]->cost < min )
			{
				temp = Q[i];
				mini = i;
				min = Q[i]->cost;
			}
		}
	}	
	Q[mini] = NULL;// delete this node
	return temp;
}

pnode huffman(int data[], int sum)
{
	pnode temp;
	memset(Q, 0, sizeof(Q));	

	int i = 0;
	int num = 0; // No. of character
	//create n node
	for(i = 0; i < ASSICN; i++)
	{
		if(data[i] != 0 ) 
		{
			temp = new node();
			if( temp == NULL )
			{
				puts("new error");
				return NULL;
			}
			temp->ch = i;
			temp->cost = data[i] * 1.0 / sum;
			temp->rchild = NULL;
			temp->lchild = NULL; 
			Q[k++] = temp;
			temp = NULL;
			num++;
		}
	}
	//allocate new node, which is not leaf
	for( i = 1; i < num; i++)
	{
		temp = new node();
		if( temp == NULL )
		{
			puts("new error");
			return NULL;
		}
		temp->lchild = extractMin();
		temp->rchild = extractMin();
		temp->ch = 0;
		temp->cost = temp->lchild->cost + temp->rchild->cost;
		Q[k++] = temp;
		temp = NULL;
	}
	return extractMin();
}


// 打印Huffman树,输出每个字符的编码
void  printTree(pnode root)
{
	if( root == NULL )
		return;
	// 0 for left
	v.push_back(0);
	printTree(root->lchild);
	v.erase(v.begin() + v.size() - 1 );// delete the last flag

	if( root->lchild == NULL )
	{
		// 对于不可打印字符,输出assic码,可打印字符则输出字符
		if( root->ch < 48 )
		{
			printf("%d(assic) : ", root->ch);
		}
		else
		{
			printf("%c(character) : ", root->ch);
		}

		for(vector<int>::iterator i = v.begin(); i != v.end(); i++ )
		{
			printf("%d", *i);
		}
		printf("\n");
	}

	// 1 for right
	v.push_back(1);
	printTree(root->rchild);
	v.erase(v.begin() + v.size() - 1 );// delete the last flag

}
int main(int argc, char* argv[])
{

	int sum = 0; // No. of input character
	int data[ASSICN];// data[i] storage the No. of assic i
	int ch;

	//initialize data[128]
	memset(data, 0, sizeof(data));
	while((ch = getchar()) != EOF)
	{
		data[ch]++;
		sum++;
	}

	pnode temp = huffman(data, sum);
	printf("\nthe sum of cost is :%lf\n", temp->cost);

	printTree( temp );
	return 0;
}


你可能感兴趣的:(算法,null,读书,delete,iterator,character)