[数据结构]课程设计--哈夫曼树编码与译码
2018-01-01 23:39
369 查看
HuffmanTree.h
hufftree.h
#pragma once
#include"HuffmanTree.h"
#include<iostream>
#include<stack>
#include<string.h>
#include"wilson_diy.h"
//初始化结点数组值
void HuffmanTree::init() {
std::cout << "请输入叶子节点数:";
std::cin >> n;
while (n < 0 || n>Max) {
std::cout << "叶子节点数应处于[0,10],请重新输入";
std::cin >> n;
}
for (int i = 0; i < 2 * n - 1; i++) {
hufftree[i].lchild = -1;
hufftree[i].parent = -1;
hufftree[i].rchild = -1;
hufftree[i].weight = 0;
}
}
//输入叶子节点值
void HuffmanTree::leaf_in() {
for (int i = 0; i < n; i++) {
std::cout << "请输入第" << i + 1 << "个叶子节点的信息"<<std::endl;
std::cout << "名字:"; std::cin >> leaf[i].name;
std::cout << "权值:"; std::cin >> leaf[i].weight;
hufftree[i].weight=leaf[i].weight;
}
}
//建树
bool HuffmanTree::create_tree() {
int i1 = 0, i2 = 0;//两个指针,指向最小的两个值
for (int k = n; k < 2 * n - 1; k++) {
select(i1, i2);//从hufftree之中选出最小权值的无双亲结点的两项,下标为i1,i2;
//设置i1,i2双亲结点为k
hufftree[i1].parent = k;
hufftree[i2].parent = k;
//i1,i2权值相加赋值给k
hufftree[k].weight = hufftree[i1].weight + hufftree[i2].weight;
//k设置孩子结点
hufftree[k].lchild = i1;
hufftree[k].rchild = i2;
}
return true;
}
//查找hufftree权值最小两点角标
void HuffmanTree::select(int &i1, int &i2) {
int i;
bool button = true;
//从第一个开始,找到的第一个未结合点角标赋值给i1,第二个赋值给i2
for (i = 0; i < 2 * n - 1; i++) {
if (button) {
if (hufftree[i].parent == -1) {
i1 = i;
button = false;
}
}
else {
if (hufftree[i].parent == -1) {
i2 = i;
break;
}
}
}
for (i = 0; i < 2 * n - 1; i++) {
if (i2 != i && hufftree[i].parent == -1 && hufftree[i].weight > 0) {
if (hufftree[i1].weight > hufftree[i].weight) {
i1 = i;
}
}
}
for (i = 0; i < 2 * n - 1; i++) {
if (i1 != i && hufftree[i].parent == -1 && hufftree[i].weight > 0) {
if (hufftree[i2].weight > hufftree[i].weight) {
i2 = i;
}
}
}
}
//显示测试
//为哈夫曼树编码,哈夫曼树结点度为2或者0
void HuffmanTree::coding() {
int c, p,
4000
start;
char cd[Max+1];
cd
= '\0';
for (int i = 0; i < n; i++)
{
c = i;
start = n;/*倒序*/
while ((p = hufftree[c].parent) != -1)/*从叶子结点开始回溯,若这个结点是其父节点的左孩子则赋值为0,反之为1*/
{
if (hufftree[p].lchild == c)
{
cd[--start] = '0';
}
else
{
cd[--start] = '1';
}
c = p;/*回溯*/
}
strcpy_s(leaf[i].code, &cd[start]);
}
}
void HuffmanTree::decoding()
{
char s[2000];
std::cin >> s;
int a, i;
a = 2 * n - 2;/*将a的值赋为根节点所在数组序号*/
i = 0;
/*从s[0]开始直到字符串结束字符'\0'*/
while (s[i] != '\0')
{
/*从根节点开始往下,若为0则往左孩子走,为1往右孩子走*/
while ((hufftree[a].lchild != -1 && hufftree[a].rchild != -1) && s[i] != '\0')
{
if (s[i] == '0')
{
a = hufftree[a].lchild;
}
else if (s[i] == '1')
{
a = hufftree[a].rchild;
}
i++;
}
//如果按所输的码译出来的不是叶子结点则报错
if (hufftree[a].lchild == -1 && hufftree[a].rchild == -1)
{
std::cout << leaf[i].name;
a = 2 * n - 2;
}
else
{
std::cout << " error! " << std::endl;
return;
}
}
}
void HuffmanTree::printtest() {
for (int i = 0; i < 2 * n - 1; i++) {
print_tab("权值", hufftree[i].weight);
print_tab("左孩子", hufftree[i].lchild);
print_tab("右孩子", hufftree[i].rchild);
print_tab("双亲结点", hufftree[i].parent);
std::cout << std::endl;
}
print_midLine();
for (int i = 0; i < n; i++) {
std::cout << leaf[i].name<<":";
std::cout << leaf[i].code<< std::endl;
std::cout << std::endl;
}
}
wilson_diy.h
#pragma once
//输出加tab
void print_tab(char a[], int b) {
std::cout << a << ":" << b << " ";
}
//比较a,b大小,输出较小的值
int Fmin(int a, int b) {
if (a <= b)return a;
else return b;
}
void print_midLine() {
std::cout << "---------------------------------------------" << std::endl;
}
test.cpp
#include"hufftree.h"
using namespace std;
int main() {
HuffmanTree huffmantree;
huffmantree.code_tree();
system("cls");
huffmantree.printtest();
cout << "输入密码";
huffmantree.decode_tree();
system("pause");
}
#pragma once const int MaxSize = 20;//哈夫曼树最大节点数 const int Max = 10;//哈夫曼树叶子节点数 //树节点 struct HFNode { int weight;//结点权值 int lchild, rchild;//孩子节点下标 int parent;//双亲结点下标 }; //初始叶子结点 struct LeafNode { int weight;//权值 char name;//叶子字符 char code[Max+1]="0";//存放编码 }; //类 class HuffmanTree { public: HuffmanTree(); ~HuffmanTree(); void printtest(); void code_tree() { coding(); } void decode_tree() { decoding(); } private: void init();//初始化树节点,parent=rchlid=lchild=-1 void leaf_in();//输入叶子节点信息 bool create_tree();//建树 void select(int &i1, int &i2); void coding();//为哈夫曼树编码 void decoding(); int n = 0;//叶子节点数 HFNode hufftree[MaxSize];//储存哈夫曼树结点信息 LeafNode leaf[Max];//储存叶子节点信息 }; HuffmanTree::HuffmanTree() { //初始化树节点,parent=rchlid=lchild=-1 init(); //输入叶子节点信息 leaf_in(); //建树 create_tree(); } HuffmanTree::~HuffmanTree() {//// }
hufftree.h
#pragma once
#include"HuffmanTree.h"
#include<iostream>
#include<stack>
#include<string.h>
#include"wilson_diy.h"
//初始化结点数组值
void HuffmanTree::init() {
std::cout << "请输入叶子节点数:";
std::cin >> n;
while (n < 0 || n>Max) {
std::cout << "叶子节点数应处于[0,10],请重新输入";
std::cin >> n;
}
for (int i = 0; i < 2 * n - 1; i++) {
hufftree[i].lchild = -1;
hufftree[i].parent = -1;
hufftree[i].rchild = -1;
hufftree[i].weight = 0;
}
}
//输入叶子节点值
void HuffmanTree::leaf_in() {
for (int i = 0; i < n; i++) {
std::cout << "请输入第" << i + 1 << "个叶子节点的信息"<<std::endl;
std::cout << "名字:"; std::cin >> leaf[i].name;
std::cout << "权值:"; std::cin >> leaf[i].weight;
hufftree[i].weight=leaf[i].weight;
}
}
//建树
bool HuffmanTree::create_tree() {
int i1 = 0, i2 = 0;//两个指针,指向最小的两个值
for (int k = n; k < 2 * n - 1; k++) {
select(i1, i2);//从hufftree之中选出最小权值的无双亲结点的两项,下标为i1,i2;
//设置i1,i2双亲结点为k
hufftree[i1].parent = k;
hufftree[i2].parent = k;
//i1,i2权值相加赋值给k
hufftree[k].weight = hufftree[i1].weight + hufftree[i2].weight;
//k设置孩子结点
hufftree[k].lchild = i1;
hufftree[k].rchild = i2;
}
return true;
}
//查找hufftree权值最小两点角标
void HuffmanTree::select(int &i1, int &i2) {
int i;
bool button = true;
//从第一个开始,找到的第一个未结合点角标赋值给i1,第二个赋值给i2
for (i = 0; i < 2 * n - 1; i++) {
if (button) {
if (hufftree[i].parent == -1) {
i1 = i;
button = false;
}
}
else {
if (hufftree[i].parent == -1) {
i2 = i;
break;
}
}
}
for (i = 0; i < 2 * n - 1; i++) {
if (i2 != i && hufftree[i].parent == -1 && hufftree[i].weight > 0) {
if (hufftree[i1].weight > hufftree[i].weight) {
i1 = i;
}
}
}
for (i = 0; i < 2 * n - 1; i++) {
if (i1 != i && hufftree[i].parent == -1 && hufftree[i].weight > 0) {
if (hufftree[i2].weight > hufftree[i].weight) {
i2 = i;
}
}
}
}
//显示测试
//为哈夫曼树编码,哈夫曼树结点度为2或者0
void HuffmanTree::coding() {
int c, p,
4000
start;
char cd[Max+1];
cd
= '\0';
for (int i = 0; i < n; i++)
{
c = i;
start = n;/*倒序*/
while ((p = hufftree[c].parent) != -1)/*从叶子结点开始回溯,若这个结点是其父节点的左孩子则赋值为0,反之为1*/
{
if (hufftree[p].lchild == c)
{
cd[--start] = '0';
}
else
{
cd[--start] = '1';
}
c = p;/*回溯*/
}
strcpy_s(leaf[i].code, &cd[start]);
}
}
void HuffmanTree::decoding()
{
char s[2000];
std::cin >> s;
int a, i;
a = 2 * n - 2;/*将a的值赋为根节点所在数组序号*/
i = 0;
/*从s[0]开始直到字符串结束字符'\0'*/
while (s[i] != '\0')
{
/*从根节点开始往下,若为0则往左孩子走,为1往右孩子走*/
while ((hufftree[a].lchild != -1 && hufftree[a].rchild != -1) && s[i] != '\0')
{
if (s[i] == '0')
{
a = hufftree[a].lchild;
}
else if (s[i] == '1')
{
a = hufftree[a].rchild;
}
i++;
}
//如果按所输的码译出来的不是叶子结点则报错
if (hufftree[a].lchild == -1 && hufftree[a].rchild == -1)
{
std::cout << leaf[i].name;
a = 2 * n - 2;
}
else
{
std::cout << " error! " << std::endl;
return;
}
}
}
void HuffmanTree::printtest() {
for (int i = 0; i < 2 * n - 1; i++) {
print_tab("权值", hufftree[i].weight);
print_tab("左孩子", hufftree[i].lchild);
print_tab("右孩子", hufftree[i].rchild);
print_tab("双亲结点", hufftree[i].parent);
std::cout << std::endl;
}
print_midLine();
for (int i = 0; i < n; i++) {
std::cout << leaf[i].name<<":";
std::cout << leaf[i].code<< std::endl;
std::cout << std::endl;
}
}
wilson_diy.h
#pragma once
//输出加tab
void print_tab(char a[], int b) {
std::cout << a << ":" << b << " ";
}
//比较a,b大小,输出较小的值
int Fmin(int a, int b) {
if (a <= b)return a;
else return b;
}
void print_midLine() {
std::cout << "---------------------------------------------" << std::endl;
}
test.cpp
#include"hufftree.h"
using namespace std;
int main() {
HuffmanTree huffmantree;
huffmantree.code_tree();
system("cls");
huffmantree.printtest();
cout << "输入密码";
huffmantree.decode_tree();
system("pause");
}
相关文章推荐
- 数据结构课程设计——编码与译码
- 【数据结构】哈夫曼树实现编码译码
- 数据结构—课程设计(城市导航系统)
- 数据结构课程设计 约瑟夫环
- 【数据结构基础】哈夫曼编码/译码课程设计
- 数据结构 课程设计哈夫曼编码
- 数据结构(C++)课程设计 3号题
- 《数据结构》课程设计题目(2)
- 数据结构 课程设计 字符串加密器
- 【“BattenSnake”数据结构课程设计总结】
- 问题:设计一个大学教师和学生管理程序, 教师包括 编号、姓名、职称和教研室 数据的输入输出; 大学生包括编号、姓名、性别、班号、英语、高等数学和数据结构三门课程成绩的输入输出和计算平均分; 研究生包
- 山东大学软件学院数据结构课程设计第一题python实现
- 《数据结构》课程设计题目
- 大学数据结构课程设计题目
- 数据结构与课程设计作业6
- stm8s 实践课程之IAP设计编码(bootloader实现)
- 数据结构-图的课程设计
- 信管1132陈玉君数据结构课程设计课题四
- 〈数据结构〉课程设计综合题目4
- 数据结构--期末课程设计