#include<vector>
#include<iostream>
#include<array>
#include<sstream>
#include<string>
#include<stack>
#include<list>
using namespace std;
typedef struct node
{
float value;
node * leftChild;
node * rightChild;
string HuffmanCode;
}Node;
/************************************************************************/
/* input numbers */
/************************************************************************/
void input(vector<Node>&ArrayNum)
{
int nums;
cout<<"input numbers of array:"<<endl;
cin>>nums;
cout<<"input numbers:"<<endl;
for (auto i=0;i<nums;i++)
{
Node temp;
cin>>temp.value;
temp.leftChild = NULL;
temp.rightChild =NULL;
ArrayNum.push_back(temp);
}
}
/************************************************************************/
/* minHeapFy */
/************************************************************************/
void MinHeapify(vector<Node>&ArrayNum,int i)
{
int leftChild = 2*i+1;
int rightChild = 2*i+2;
int minPos = i;
if (leftChild<=ArrayNum.size()-1&&ArrayNum[leftChild].value<ArrayNum[i].value)
{
minPos = leftChild;
}
if (rightChild<=ArrayNum.size()-1&&ArrayNum[rightChild].value<ArrayNum[minPos].value)
{
minPos = rightChild;
}
if (minPos == i)
{
return;
}
swap(ArrayNum[i],ArrayNum[minPos]);
MinHeapify(ArrayNum,minPos);
}
/************************************************************************/
/* build Heap */
/************************************************************************/
void buildMinHeap(vector<Node>&ArrayNum)
{
for (int i = ArrayNum.size()/2 -1;i!=-1;i--)
{
MinHeapify(ArrayNum,i);
}
}
/************************************************************************/
/* extract-min */
/************************************************************************/
Node ExtractMin(vector<Node>&ArrayNum)
{
Node result = ArrayNum[0];
swap(ArrayNum[ArrayNum.size()-1],ArrayNum[0]);
ArrayNum.erase(ArrayNum.end()-1);
if (!ArrayNum.empty())
{
MinHeapify(ArrayNum,0);
}
return result;
}
/************************************************************************/
/* insert a node into the heap */
/************************************************************************/
void insertNode(vector<Node>&ArrayNum,Node p)
{
ArrayNum.push_back(p);
int p_pos =ArrayNum.size()-1;
int p_parent = (p_pos-1)/2;
while(p_parent>=0 && ArrayNum[p_pos].value<ArrayNum[p_parent].value)
{
swap(ArrayNum[p_pos],ArrayNum[p_parent]);
p_pos = p_parent;
p_parent = (p_pos-1)/2;
}
}
/************************************************************************/
/* 递归遍历二叉树并生成huffman码,存在每个节点中 */
/************************************************************************/
void visitBiTree(Node & root)
{
if (&root!=NULL )
{
if (root.leftChild!=NULL)
{
root.leftChild->HuffmanCode = root.HuffmanCode+"0";
visitBiTree(*root.leftChild);
}
if (root.rightChild!=NULL)
{
root.rightChild->HuffmanCode = root.HuffmanCode+"1";
visitBiTree(*root.rightChild);
}
}
}
/************************************************************************/
/* output huffman code */
/************************************************************************/
void outputHuffmanCode(Node const& root)
{
if (&root!=NULL)
{
cout<<root.value<<":"<<root.HuffmanCode<<endl;
outputHuffmanCode(*root.leftChild);
outputHuffmanCode(*root.rightChild);
}
}
int main()
{
vector<Node>ArrayNum;
input(ArrayNum);
buildMinHeap(ArrayNum);
int originNumber = ArrayNum.size();
/************************************************************************/
/* 利用堆,每次从小根堆中抽取最小的两个数,生成一个新节点,将这两个数作为新节点的孩子,
新节点的值为两者值之和,将新节点加入堆中*/
/************************************************************************/
for (int i=0;i<originNumber-1;i++)
{
Node * leftLeaf = new Node;
*leftLeaf = ExtractMin(ArrayNum);
Node * rightLeaf = new Node;
* rightLeaf = ExtractMin(ArrayNum);
Node * parent = new Node;
parent->leftChild = leftLeaf;
parent->rightChild = rightLeaf;
parent->value = leftLeaf->value+rightLeaf->value;
insertNode(ArrayNum,*parent);
}
Node root = ExtractMin(ArrayNum);
root.HuffmanCode = "";
visitBiTree(root);
outputHuffmanCode(root);
system("pause");
}
Huffman编码
最新推荐文章于 2024-05-08 22:04:44 发布