为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

c++哈夫曼编码与译码

2017-09-20 10页 doc 28KB 45阅读

用户头像

is_180829

暂无简介

举报
c++哈夫曼编码与译码c++哈夫曼编码与译码 #include #include //系统自带的字符串库函数 using namespace std; struct Node { char data; // 节点数据域为字符型 Node *next; Node(){ next = NULL;}; Node(char item, Node *link = NULL){ data = item; next = link;}; }; class LinkList {//仅保留几个用得到的成员函数 protected: Node *...
c++哈夫曼编码与译码
c++哈夫曼编码与译码 #include #include //系统自带的字符串库 using namespace std; struct Node { char data; // 节点数据域为字符型 Node *next; Node(){ next = NULL;}; Node(char item, Node *link = NULL){ data = item; next = link;}; }; class LinkList {//仅保留几个用得到的成员函数 protected: Node *head; Node *curPtr; int count,curPosition; Node *GetElemPtr(int position); // 返回指向第position个结点的指针 public: LinkList(); int Length() const; bool Empty() const; void Traverse() ; void Insert(int position, const char &e); char GetElem(int position) ; }; Node * LinkList::GetElemPtr(int position) { if (curPosition > position) { curPosition = 0; curPtr = head; } for (; curPosition < position; curPosition++) curPtr = curPtr->next; return curPtr; } char LinkList::GetElem(int position) { Node *tmr; tmpPtr = GetElemPtr(position); char e = tmpPtr->data; return e; } LinkList::LinkList() { head = new Node; // 构造头指针,带头结点的链表 curPtr = head; curPosition =0; count = 0; } int LinkList::Length() const { return count; } bool LinkList::Empty() const { return head->next == NULL; } void LinkList::Traverse() { for (Node *tmpPtr = head->next; tmpPtr != NULL; tmpPtr = tmpPtr->next) { cout<<(tmpPtr->data); } } void LinkList::Insert(int position, const char &e) { Node *tmpPtr; tmpPtr = GetElemPtr(position - 1); Node *newPtr; newPtr = new Node(e, tmpPtr->next); tmpPtr->next = newPtr; curPosition = position; curPtr = newPtr; count++; } // 哈夫曼树结点类 struct HuffmanTreeNode { int weight; unsigned int parent, leftChild, rightChild; // 双亲,左右孩子域 HuffmanTreeNode(); HuffmanTreeNode(int w, int p = 0, int lChild = 0, int rChild = 0); }; HuffmanTreeNode::HuffmanTreeNode() { parent = leftChild = rightChild = 0; } HuffmanTreeNode::HuffmanTreeNode(int w, int p, int lChild, int rChild) // 右孩子 { weight = w; // 权 parent = p; // 双亲 leftChild = lChild; // 左孩子 rightChild = rChild; // 右孩子 } class HuffmanTree { protected: // HuffmanTreeNode *nodes; // 存储结点信息,nodes[0]未用 char *LeafChars; // 叶结点字符信息,LeafChars[0]未用 string *LeafCharCodes; // 叶结点字符编码信息,LeafCharCodes[0]未用 int curPos; // 译码时从根结点到叶结点路径的当前结点 int num; // 叶结点个数 // 辅助函数: void Select(int cur, int &r1, int &r2); // nodes[1 ~ cur]中选择双亲为0,权值最小的两个结点 r1,r2 void CreatHuffmanTree(char ch[], int w[], int n); public: HuffmanTree(char ch[], int w[], int n); // 由字符,权值和字符个数构造哈夫曼树 virtual ~HuffmanTree(); // 析构函数 string Encode(char ch); // 编码 LinkList Decode(string strCode); // 译码 }; void HuffmanTree::Select(int cur, int &r1, int &r2) { r1 = r2 = 0; // 0表示空结点 for (int pos = 1; pos <= cur; pos++) { if (nodes[pos].parent != 0) continue; // 只处理双亲为0的结点 if (r1 == 0) { r1 = pos; } else if (r2 == 0) { r2 = pos; } else if (nodes[pos].weight < nodes[r1].weight) { r1 = pos; } else if (nodes[pos].weight < nodes[r2].weight) { r2 = pos; } } } void HuffmanTree::CreatHuffmanTree(char ch[], int w[], int n) { num = n; // 叶结点个数 int m = 2 * n - 1; // 结点个数 nodes = new HuffmanTreeNode[m + 1]; // nodes[0]未用 LeafChars = new char[n + 1]; // LeafChars[0]未用 LeafCharCodes = new string[n + 1]; // LeafCharCodes[0]未用 int pos; // 临时变量 for (pos = 1; pos <= n; pos++) { // 存储叶结点信息 nodes[pos].weight = w[pos - 1]; // 权值 LeafChars[pos] = ch[pos - 1]; // 字符 } for (pos = n + 1; pos <= m; pos++) { // 建立哈夫曼树 int r1, r2; Select(pos - 1, r1, r2); nodes[r1].parent = nodes[r2].parent = pos; // r1,r2双亲为pos nodes[pos].leftChild = r1; // r1为pos的左孩子 nodes[pos].rightChild = r2; // r2为pos的右孩子 nodes[pos].weight = nodes[r1].weight + nodes[r2].weight;//pos的权为r1,r2的权值之和 } for (pos = 1; pos <= n; pos++) { // 求n个叶结点字符的编码 LinkList charCode; // 暂存叶结点字符编码信息 for (unsigned int child = pos, parent = nodes[child].parent; parent != 0; child = parent, parent = nodes[child].parent) { if (nodes[parent].leftChild == child) charCode.Insert(1,'0'); else charCode.Insert(1,'1');; } for(int i=1;i<=charCode.Length();i++) LeafCharCodes[pos].append(1, charCode.GetElem(i));//没有直接可以从链表为字符串赋 值的函数,只能一个字符一个字符的追加过去 } curPos = m; } HuffmanTree::HuffmanTree(char ch[],int w[], int n) { CreatHuffmanTree(ch, w, n); } HuffmanTree::~HuffmanTree() { if (nodes != NULL) delete []nodes; // 释放结点信息 if (LeafChars != NULL) delete []LeafChars; // 释放叶结点字符信息 if (LeafCharCodes != NULL) delete []LeafCharCodes; // 释放叶结点字符编码信息 } string HuffmanTree::Encode(char ch) { for (int pos = 1; pos <= num; pos++) { if (LeafChars[pos] == ch) return LeafCharCodes[pos];// 找到字符,得到编码 } } LinkList HuffmanTree::Decode(string strCode) // 操作结果:对编码串strCode进行译码,返回编码前的字符序列 { LinkList charList; // 编码前的字符序列 for (int pos = 0; pos < strCode.length(); pos++) { // 处理每位编码 if (strCode[pos] == '0') curPos = nodes[curPos].leftChild; // '0'表示左分支 else curPos = nodes[curPos].rightChild; // '1'表示左分支 if (nodes[curPos].leftChild == 0 && nodes[curPos].rightChild == 0) { // 译码时从根结点到叶结点路径的当前结点为叶结点 charList.Insert(charList.Length() + 1, LeafChars[curPos]); curPos = 2 * num - 1; } } return charList; } int main(void) { char *ch; int *w,n,i; cout<<"输入字符集中字符的个数:"<>n; ch=new char[n]; w=new int[n]; cout<<"输入字符集中的字符:"<>ch[i]; cout<<"输入字符集中的字符的权值:"<>w[i]; HuffmanTree hmTree(ch, w, n); string strText,strCode; cout<<"请输入要编码的字符串"; cin>>strText; cout << "文本串" << strText.c_str()<< "编码为:"; for (int pos = 0; pos < strText.length(); pos++) { string strTmp = hmTree.Encode(strText[pos]); cout << strTmp.c_str(); } cout << endl; system("PAUSE"); cout<<"请输入要译码的二进制串"; cin>>strCode; cout << "编码串" << strCode.c_str()<< "译码为:"; LinkList lkText = hmTree.Decode(strCode); lkText.Traverse(); system("PAUSE"); return 0; }
/
本文档为【c++哈夫曼编码与译码】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索