Huffuman 编码问题:
变长编码(variable-length code)可以达到比定长编码好很多的压缩率,其思想史赋予高频字符短码字,低频字符长码字。前缀码(prefix code)可以保证
没有任何码字是其他码字的前缀。赫夫曼编码采用依赖于贪心算法选择性质和最优子结构 构造最优前缀码。
其执行过程如下: 选择当前最小的两个节点作为树左右子节点,并把和作为下次统计的对象中。
构造hafuman树: 选取当前最小频率的两个节点,作为树的左右子节点,按从下往上的顺序构Huffman树。最后返回根节点
node getHuffmanTree()
{
while(!nodeArray.empty())
{
node * tempNode = new node;
node * tempNode1 = new node;
node * tempNode2 = new node;
*tempNode1 = extractMin();
*tempNode2 = extractMin();
tempNode->leftChild = tempNode1;
tempNode->rightChild = tempNode2;
tempNode->frequency = tempNode1->frequency+tempNode2->frequency;
nodeArray.push_back(*tempNode);
if(nodeArray.size() == 1)//only the root node exsits
{
break;
}
}
return nodeArray[0];
}
哈弗曼 编码: s.erase(s.end()-1); 是往父节点回退,从而按从上往下层级、左,中,右顺序 遍历完树
void BFS(node * temproot,string s)
{
node * root1 = new node;
root1 = temproot;
root1->code = s;
if(root1 == NULL)
{
}
else if(root1->leftChild == NULL && root1->rightChild == NULL)
{
cout<<"the content is "<<root1->content<<endl;
cout<<"and its corresponding code is "<<root1->code<<endl;
}
else
{
root1->leftChild->code = s.append("0");
s.erase(s.end()-1);
root1->rightChild->code = s.append("1");
s.erase(s.end()-1);
BFS(root1->leftChild,s.append("0"));
s.erase(s.end()-1);
BFS(root1->rightChild,s.append("1"));
s.erase(s.end()-1);
}
}
最后记下 动态规划和贪心算法的不同,虽然都具有最优子结构性质(问题最优解包含子问题最优解), 贪心算法仅仅是做出局部最优来构造全局最优,不考虑子问题的解。而动态规划,每次进行选择通常依赖子问题的解,自底向上的方式,先求解子问题,然后较大子问题。贪心算法总是做出当时看来最佳,然后求解剩余子问题,与将来的问题无关。
参考:
https://en.wikipedia.org/wiki/Huffman_coding
《算法导论》