《数据结构实战》------------------------------------------------------ 霍夫曼算法的实现

霍夫曼算法的实现。

#ifndef __CHUFFMANCODE__H
#define __CHUFFMANCODE__H
#include <iostream>
#include <string>
#include <functional>
#include <queue>

//哈夫曼编码

struct TreeNode
{
	std::string strName;
	int         nFrequence; // 出现的频率
	int         nWight; // 权值
	TreeNode*   pLeftTree; // 左子树
	TreeNode*   pRightTree; // 右子树
	TreeNode()
	{
		strName = "";
		nFrequence = 0;
		nWight = 0;
		pLeftTree = nullptr;
		pRightTree = nullptr;
	}
};

class cmp
{

public:
	cmp(TreeNode* pNode) : m_pNode(pNode)
	{}

	bool operator< (const cmp& rhs) const
	{
		return m_pNode->nWight > rhs.m_pNode->nWight;
	}

public:
	TreeNode* m_pNode;
};


class CHuffmanCode
{
public:
	CHuffmanCode();
	~CHuffmanCode();

public:
	void InsertNode(std::string strName, int nFrequence);
	void Generater(); // 生成哈夫曼树
	void PrintHuffmanCode(); // 打印编码
private:
	void DeleteTree(TreeNode*& pNode);
	void PrintHuffmanCode(TreeNode* pNode, std::queue<std::string>& strQueue);
private:
	TreeNode* m_pRoot; // 最终生成的哈夫曼树
	std::priority_queue<cmp> m_queue; // 最小堆
};

#endif

#include "HuffmanCode.h"



CHuffmanCode::CHuffmanCode()
{
}


CHuffmanCode::~CHuffmanCode()
{
	DeleteTree(m_pRoot);
}

void CHuffmanCode::InsertNode(std::string strName, int nFrequence) // 为简单起见,由调用者保证不重复
{
	TreeNode* pNode = new TreeNode;
	pNode->strName = strName;
	pNode->nFrequence = nFrequence;
	pNode->nWight = nFrequence;
	m_queue.push(pNode);
}

void CHuffmanCode::Generater()
{
	TreeNode* pNode = nullptr;
	while (!m_queue.empty())
	{
		pNode = m_queue.top().m_pNode;
		m_queue.pop();
		if (m_queue.empty())
			break;
		TreeNode* pSecond = m_queue.top().m_pNode;
		m_queue.pop();
		TreeNode* pNew = new TreeNode; // 生成新的节点
		pNew->pLeftTree = pNode;
		pNew->pRightTree = pSecond;
		pNew->nWight = pNew->pLeftTree->nWight + pNew->pRightTree->nWight;
		m_queue.push(pNew);
	}
	m_pRoot = pNode;
}

void CHuffmanCode::DeleteTree(TreeNode*& pNode)
{
	if (!pNode)
		return;
	DeleteTree(pNode->pLeftTree);
	DeleteTree(pNode->pRightTree);
	delete pNode;
	pNode = nullptr;
}

void CHuffmanCode::PrintHuffmanCode()
{
	std::queue<std::string> strQueue;
	PrintHuffmanCode(m_pRoot, strQueue);
}

void CHuffmanCode::PrintHuffmanCode(TreeNode* pNode, std::queue<std::string>& strQueue)
{
	if (pNode->strName != "")
	{
		strQueue.push(pNode->strName);
		std::queue<std::string> swapQueue;
		while (!strQueue.empty())
		{
			std::string str = strQueue.front();
			std::cout << str.c_str();
			strQueue.pop();
			if (!strQueue.empty()) // 最后一个不push
				swapQueue.push(str);
		}
		swapQueue.swap(strQueue);
		std::cout << std::endl;
	}
	if (pNode->pLeftTree)
	{
		strQueue.push("0"); // 左子树的边是0
		PrintHuffmanCode(pNode->pLeftTree, strQueue);
		strQueue.pop();
	}
	if (pNode->pRightTree)
	{
		strQueue.push("1"); // 右子树的边是1
		PrintHuffmanCode(pNode->pRightTree, strQueue);
		strQueue.pop();
	}
}

#include "HuffmanCode.h"

int main()
{
	CHuffmanCode huffman;
	huffman.InsertNode("a", 10);
	huffman.InsertNode("e", 15);
	huffman.InsertNode("i", 12);
	huffman.InsertNode("s", 3);
	huffman.InsertNode("t", 4);
	huffman.InsertNode("sp", 13);
	huffman.InsertNode("nl", 1);

	huffman.Generater();
	huffman.PrintHuffmanCode();
	std::cin.get();
	return 0;
}
下图是哈夫曼的初始状态,及编码后的状态


猜你喜欢

转载自blog.csdn.net/li2818/article/details/73251900