自适应Huffman编码,可用初始编码表(数字音视频技术,实验二)

如果你已经理解了 自适应Huffman编码 ,那么你不应该浪费时间在无聊的实验上

实验目的

1、深入掌握自适应Huffman编码的原理
2、掌握自适应Huffman编码算法的实现过程
3、掌握和熟悉利用编程语言实现自适应Huffman编码器和解码器

实验要求

1、实现编码器,对输入字符给出相应的编码结果;
2、实现解码器,对步骤1中的编码结果进行解码;
3、请使用初始编码表如下:

4、对字符串ABBCADAD进行编码;
5、截图显示编码中间结果,并保证最终解码结果正确;
6、编辑程序说明文档。

实验步骤

附实验代码及说明文档

实验体会

记录实验过程中碰到的问题及解决方法、最终实验结果。

实现代码:

cpp文件,main函数里包含初始编码表 代码片.

#include "huffmanTree.h"
#include <map>
map<char, string> initCode;BinaryTree::BinaryTree(int num, int weight)
{p_root = new Node(nullptr, nullptr, nullptr);p_root->num = num; //节点的序号p_root->weight = weight;  //节点的权重值
}BinaryTree::~BinaryTree()
{deleteNode(p_root);
}bool BinaryTree::swap(Node * p_nodeA, Node * p_nodeB)
{if (p_nodeA == nullptr || p_nodeB == nullptr || p_nodeA == p_nodeB)return false;Node *pTemp;if (getBrotherState(p_nodeA) == LeftChild) { //如果A节点是左孩子if (getBrotherState(p_nodeB) == LeftChild) { // 如果B节点是左孩子pTemp = p_nodeA->p_parent->p_left;p_nodeA->p_parent->p_left = p_nodeB->p_parent->p_left;p_nodeB->p_parent->p_left = pTemp;}else {pTemp = p_nodeA->p_parent->p_left;p_nodeA->p_parent->p_left = p_nodeB->p_parent->p_right;p_nodeB->p_parent->p_right = pTemp;}}else {if (getBrotherState(p_nodeB) == LeftChild) {pTemp = p_nodeA->p_parent->p_right;p_nodeA->p_parent->p_right = p_nodeB->p_parent->p_left;p_nodeB->p_parent->p_left = pTemp;}else {pTemp = p_nodeA->p_parent->p_right;p_nodeA->p_parent->p_right = p_nodeB->p_parent->p_right;p_nodeB->p_parent->p_right = pTemp;}}pTemp = p_nodeA->p_parent;p_nodeA->p_parent = p_nodeB->p_parent;p_nodeB->p_parent = pTemp;return true;}bool BinaryTree::addNode(Node * p_parent, Node * p_child, Brother brotherState)
{if (p_parent == nullptr || p_child == nullptr)return false;if (brotherState == LeftChild) { if (p_parent->p_left != nullptr) {std::cout << "error:left child exist!" << std::endl;return false;//如果父节点有左孩子,则不能添加到左孩子位置}p_parent->p_left = p_child;//否则可以添加}else if (brotherState == RightChild) { if (p_parent->p_right != nullptr) {std::cout << "error:right child exist!" << std::endl;return false;//如果父节点有右孩子,则不能添加到右孩子位置}p_parent->p_right = p_child;//否则可以添加}else {std::cout << "error:brotherState is wrong!" << std::endl;//读取位置信息错误return false;}p_child->p_parent = p_parent;return true;
}bool BinaryTree::isAncestor(Node * p_nodeChild, Node * p_nodeAncestor)
{while (p_nodeChild != p_root) {if (p_nodeChild == p_nodeAncestor) {return true;}else {p_nodeChild = p_nodeChild->p_parent;}}return false;
}void BinaryTree::deleteNode(Node *p_node)
{if (p_node->p_left != nullptr) {deleteNode(p_node->p_left);}if (p_node->p_right != nullptr) {deleteNode(p_node->p_right);}delete p_node;
}BinaryTree::Brother BinaryTree::getBrotherState(Node *p_node)
{if (p_node->p_parent->p_left == p_node) {return LeftChild;}else {return RightChild;}
}HuffmanTree::HuffmanTree() :tree(0, 0)
{sum = 1;
}string HuffmanTree::getHuffmanCode(Node *p_n)
{std::string huffmanCode = "";std::stack<Node *> stack;std::deque<char> code;if (p_n == tree.getRoot())return "0";while (p_n != tree.getRoot()) {if (tree.getBrotherState(p_n) == tree.LeftChild) {code.push_back('0');}else {code.push_back('1');}p_n = p_n->p_parent;}while (!code.empty()) {huffmanCode += code.back();code.pop_back();}return huffmanCode;
}Node * HuffmanTree::findLarge(Node *p_node)
{std::stack<Node *> stack;Node *p = tree.getRoot();Node *large = p;while (p || !stack.empty()) {if (p != nullptr) {stack.push(p);if (p->weight == p_node->weight) {//如果large不在同权重下,则置large为pif (large->weight != p->weight) {large = p;}//同权重下的large比p小,则置large为pelse if (large->num > p->num) {large = p;}}p = p->p_left;}else {p = stack.top();stack.pop();p = p->p_right;}}if (large == tree.getRoot()) {return p_node;}return large;
}void HuffmanTree::encode( string input)
{char cbuffer;Node *nyt = tree.getRoot();bool exist = false;for (int i = 0; i < input.length(); i++) { cbuffer = input[i];     exist = false;string code;auto existNode = buffers.begin();   for (existNode; existNode != buffers.end(); existNode++) {if (existNode->key == cbuffer) {code = existNode->value;exist = true;cout << cbuffer << " 在树中存在,编码为: " << existNode->value << endl; break;}}if (exist) { Node *root = existNode->p;weightAdd(root);}else {Node *c = new Node(nullptr, nullptr, nyt);c->num = sum++;c->weight = 1;Node *NYT = new Node(nullptr, nullptr, nyt);NYT->num = sum++;NYT->weight = 0;cout << "\n NYT:" << getHuffmanCode(nyt) << endl;tree.addNode(nyt, NYT, BinaryTree::LeftChild);tree.addNode(nyt, c, BinaryTree::RightChild);nyt->weight = 1;cout << cbuffer << "首次出现,编码为:"<< initCode.at(cbuffer) << endl;charMap* new_cm = new charMap();new_cm->key = cbuffer;new_cm->p = nyt->p_right;new_cm->value = getHuffmanCode(nyt->p_right);buffers.push_back(*new_cm);Node *root = nyt->p_parent;weightAdd(root);nyt = nyt->p_left;}}}void HuffmanTree::weightAdd(Node * p_node)
{while (p_node != nullptr) {Node* large = findLarge(p_node);if (large != p_node && !tree.isAncestor(p_node, large)) {            tree.swap(large, p_node);int temp;temp = large->num;large->num = p_node->num;p_node->num = temp;for (auto iterator = buffers.begin(); iterator != buffers.end(); iterator++) {iterator->value = getHuffmanCode(iterator->p);}}p_node->weight++;      p_node = p_node->p_parent;}
}void HuffmanTree::decode(string input)
{Node *nyt = tree.getRoot();int p = 0;int l = 1;string temp;bool exit = false;for (;p+l<= input.length();){exit = false;temp = input.substr(p, l);cout << "\n循环: " << temp ;//如果是NYT,说明有新的if (temp == getHuffmanCode(nyt)) {p+=l;l = 5;temp = input.substr(p, l);//在字典中寻找对应值for (auto iter = initCode.begin(); iter != initCode.end(); ++iter) {string cur = iter->second;if (cur == temp){//找到了就加新的cout << "      新码的:" << iter->first << endl;Node *c = new Node(nullptr, nullptr, nyt);c->num = sum++;c->weight = 1;Node *NYT = new Node(nullptr, nullptr, nyt);NYT->num = sum++;NYT->weight = 0;tree.addNode(nyt, NYT, BinaryTree::LeftChild);tree.addNode(nyt, c, BinaryTree::RightChild);nyt->weight = 1;charMap* new_cm = new charMap();new_cm->key = iter->first;new_cm->p = nyt->p_right;new_cm->value = getHuffmanCode(nyt->p_right);buffers.push_back(*new_cm);//依次增加权重Node *root = nyt->p_parent;weightAdd(root);//设置新的nyt节点为原nyt节点的左孩子nyt = nyt->p_left;}}p += l;l = 1;exit = true;}else//如果不是NYT,就在树里面找{auto existNode = buffers.begin();for (existNode; existNode != buffers.end(); existNode++) {if (existNode->value == temp) {//找到cout  << "     在树中存在,为: " << existNode->key << endl;Node *root = existNode->p;weightAdd(root);p += l;l = 1;exit = true;break;}}}//如果即不再树中也不在字典中,l++if(!exit)l++;}}//主函数程序
int main()
{HuffmanTree huff;//这个字典是初始编码表initCode['A'] = "00001";initCode['B'] = "00010";initCode['C'] = "00011";initCode['D'] = "00100";string input = "ABBCADAD";huff.encode(input);//进行编码的函数//以下是解码函数HuffmanTree dhuff;dhuff.decode("0000010000100100000110110000100111001");system("PAUSE");return 0;
}

.h头文件 代码片.

#pragma once
#include <fstream>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<string>using namespace std;struct Node {int weight; int num;  Node* p_left; Node* p_right;  Node* p_parent; Node(Node* p_left, Node* p_right, Node* p_parent) : p_left(p_left), p_right(p_right), p_parent(p_parent) {};
};class BinaryTree
{public:enum Brother { LeftChild, RightChild };BinaryTree(int num = 0, int weight = 0);~BinaryTree();bool swap(Node* p_nodeA, Node* p_nodeB);bool addNode(Node* p_parent, Node* p_child, Brother brotherState);Node* findNode(string in);void deleteNode(Node *p_node);Node* getRoot() { return p_root; }Brother getBrotherState(Node *p_node);bool isAncestor(Node* p_nodeChild, Node* p_nodeAncestor);
private:Node *p_root;};class HuffmanTree
{public:int sum;HuffmanTree();void encode(string input);void weightAdd(Node* p_node);void decode(string input);BinaryTree tree;struct charMap {char key;std::string value;Node* p;};vector<charMap> buffers;string getHuffmanCode(Node *p);Node * findLarge(Node *);}; 
  • 源代码修改自https://blog.csdn.net/qq_36533706/article/details/80381457?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163819021616780366596114%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=163819021616780366596114&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-80381457.first_rank_v2_pc_rank_v29&utm_term=%E8%87%AA%E9%80%82%E5%BA%94Huffman%E7%BC%96%E7%A0%81&spm=1018.2226.3001.4187

自适应Huffman编码相关推荐

  1. huffman树和huffman编码

    不知道为什么,我写的代码都是又臭又长. 直接上代码: #include <iostream> #include <cstdarg> using namespace std; c ...

  2. 技术图文:如何利用C#实现Huffman编码?

    背景 Huffman编码 在通信和数据压缩领域具有重要的应用. 在介绍 Huffman 编码具体实现之前,先介绍几个相关的概念. 概念1:树中结点的带权路径长度 – 根结点到该结点的路径长度与该结点权 ...

  3. huffman java_详解Huffman编码算法之Java实现

    Huffman编码介绍 Huffman编码处理的是字符以及字符对应的二进制的编码配对问题,分为编码和解码,目的是压缩字符对应的二进制数据长度.我们知道字符存贮和传输的时候都是二进制的(计算机只认识0/ ...

  4. Huffman 编码压缩算法

    为什么80%的码农都做不了架构师?>>>    前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过 David Huf ...

  5. 采用Huffman编码进行数据压缩

    文章目录 问题 实验环境 程序组成 实现思路 如何用二进制0/1表示字符 '0' / '1' 源代码下载 程序运行和结果: 总结 问题 利用哈夫曼编码将英文文献进行压缩 注:哈夫曼算法及原理见博客ht ...

  6. huffman编码压缩算法

    转自:http://coolshell.cn/articles/7459.html 前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法.相信大家应该听说过  ...

  7. 数据结构实验三:Huffman树及Huffman编码的算法实现

    Exp03 Huffman树及Huffman编码的算法实现 Author: Maskros 实验目的 了解该树的应用实例,熟悉掌握Huffman树的构造方法及Huffman编码的应用, 了解Huffm ...

  8. Huffman编码(Huffman树)

    [0]README 0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解 "Huffman编码(Huffman树)" 的idea 并用源代码加以实现: 0.2) ...

  9. huffman编码的程序流程图_Huffman编码实现压缩解压缩

    这是我们的课程中布置的作业.找一些资料将作业完毕,顺便将其写到博客,以后看起来也方便. 原理介绍 什么是Huffman压缩 Huffman( 哈夫曼 ) 算法在上世纪五十年代初提出来了,它是一种无损压 ...

最新文章

  1. 如何找回误删并清除了回收站的文档
  2. mysql中的字符匹配查询
  3. linux宝塔面板配置可道云,使用宝塔面板配合可道云打造私有云
  4. 【蓝桥杯Java_C组·从零开始卷】第一节、环境与变量类型运算符与类型分析
  5. 程序填充(指针):3数排序_排序算法之快速排序,它为什么这么快?
  6. PPT到底是天使还是魔鬼?
  7. Python Unittest参数化parameterized之数据驱动
  8. 程序员的修炼之道——从小工到专家
  9. matlab2c使用c++实现matlab函数系列教程-triu函数
  10. Sublime text2 插件推荐
  11. 2020家用千兆路由器哪款好_千兆路由器哪个好 2020年值得入手的家用千兆路由器推荐...
  12. 不要随意设置随机数种子
  13. 面向对象的软件开发方法
  14. Service phantomjs unexpectedly exited. Status code was: 1
  15. 角度前方交会点坐标计算完整步骤
  16. 开发中的各种时间格式转换(一)
  17. 基于 Ng-zorro-antd 的企业后台模板 ng-alain
  18. Multi-Scale Context Aggregation By Dilated Convolutions
  19. 集肤效应、邻近效应、边缘效应、涡流损耗
  20. Python:实现floor向下取整算法(附完整源码)

热门文章

  1. 解决电脑速度慢的问题
  2. uboot drm框架
  3. Webview 打开qq聊天窗口,申请进群
  4. Circular Billiard Table(计算几何)
  5. scratch一级考纲
  6. 2021第十三届中国最佳酒店大奖榜单揭晓:年度最佳酒店、最佳顶级奢华酒店、最佳城市地标酒店...
  7. 一起用Python做个自动化短视频生成脚本,实现热门视频流水线生产!
  8. Mask R-CNN 训练自己的数据集—踩坑与填坑
  9. 最好的防御就是进攻 任正非
  10. PCIE操作基础原理