刚学完数据结构Huffman树,以此练一下手~(顺便写下第一篇日志)
基础不好啊~写得很快,就是查错查了半天……
最后总算运行正确了~
HuffmanCoding函数基本都写的差不多,Select函数是自己写的,写的当然不够飘逸啦,但是至少思路是对的吧~
我在代码后面都写了详细的注释~
以下是代码:
#include <iostream>
#include <string>
#include <string>
#define MAXSIZE 100
using namespace std;
typedef struct {
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char ** HuffmanCode;
void Select (HuffmanTree HT,int j,int &s1,int &s2) { //Select函数
int i = 1;
int i = 1;
int unsigned tmp1,tmp2;
tmp1 = unsigned int (-1); //令tmp1和tmp2为最大的unsigned的数
tmp2 = unsigned int (-1);
int num1=0,num2=0;
tmp1 = unsigned int (-1); //令tmp1和tmp2为最大的unsigned的数
tmp2 = unsigned int (-1);
int num1=0,num2=0;
for (i=1;i<=j;++i) {
if (HT[i].parent==0) { //当某个元素的parent!=0时说明此元素已经被用过了,所以不能再作算
if (HT[i].weight < tmp1) { //先选一个weigth最小的元素
tmp1 = HT[i].weight;
num1 = i; //用num1记录编号
}
}
}
if (HT[i].parent==0) { //当某个元素的parent!=0时说明此元素已经被用过了,所以不能再作算
if (HT[i].weight < tmp1) { //先选一个weigth最小的元素
tmp1 = HT[i].weight;
num1 = i; //用num1记录编号
}
}
}
for (i=1;i<=j;++i) {
if (HT[i].parent==0) { //同上
if (HT[i].weight <= tmp2 && HT[i].weight >= tmp1 && i!=num1) {
//选一个比tmp1大的数中的最小权值元素赋值给tmp2.
//i!=num1表示取过的元素项不能再取
if (HT[i].weight!=tmp2) {
//这里条件表示如果权值为tmp2的好几个,就取第一个为tmp2的编号
tmp2 = HT[i].weight;
num2 = i;
}
}
}
}
if (num1<num2) { //保证s1<s2
s1 = num1;
s2 = num2;
}
else {
s1 = num2;
s2 = num1;
}
}
if (HT[i].parent==0) { //同上
if (HT[i].weight <= tmp2 && HT[i].weight >= tmp1 && i!=num1) {
//选一个比tmp1大的数中的最小权值元素赋值给tmp2.
//i!=num1表示取过的元素项不能再取
if (HT[i].weight!=tmp2) {
//这里条件表示如果权值为tmp2的好几个,就取第一个为tmp2的编号
tmp2 = HT[i].weight;
num2 = i;
}
}
}
}
if (num1<num2) { //保证s1<s2
s1 = num1;
s2 = num2;
}
else {
s1 = num2;
s2 = num1;
}
}
void HuffmanCoding (HuffmanTree &HT,HuffmanCode &HC,int *w,int n,char *elem) {
//*w处传入数组,代表各个元素的权数
//*elem处传入元素(可以在main函数中实现,在这里是为了在函数体内实现才
//多加的参数)
if (n<=1) return;
int m=2*n-1;
int i;
HuffmanTree p;
p = (HuffmanTree)malloc(sizeof(HTNode));
HT = (HuffmanTree)malloc((m+1)*sizeof(HTNode));
//初始化表格
for (p=HT+1,i=1;i<=n;++i,++p,++w) {
p->weight = *w;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
for (;i<=m;++i,++p) {
p->parent = 0;
p->rchild = 0;
p->lchild = 0;
p->weight = 0;
}
//往表格中填入元素
for (i=n+1;i<=m;++i) {
int s1,s2;
Select (HT,i-1,s1,s2); //从表中选出最小的2个数,并且不改变次序
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
HT[s1].parent = i;
HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].weight = HT[s1].weight + HT[s2].weight;
}
//从叶子到根为字符编码
HC = (HuffmanCode)malloc((n+1)*sizeof(char*));
int start,c,f;
HC = (HuffmanCode)malloc((n+1)*sizeof(char*));
int start,c,f;
char *cd;
cd = (char *)malloc(n*sizeof(char));
cd[n-1] = '/0';
for (i=1;i<=n;++i) {
start = n-1;
for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) {
if (HT[f].lchild == c) cd[--start] = '0'; //左子树编码为0
else cd[--start] = '1'; //右子数编码为1
}
cd = (char *)malloc(n*sizeof(char));
cd[n-1] = '/0';
for (i=1;i<=n;++i) {
start = n-1;
for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent) {
if (HT[f].lchild == c) cd[--start] = '0'; //左子树编码为0
else cd[--start] = '1'; //右子数编码为1
}
HC[i] = (char*)malloc((n-start)*sizeof(char));
strcpy (HC[i],&cd[start]); //把代码反置(因为从叶子到根,代码是反得)
strcpy (HC[i],&cd[start]); //把代码反置(因为从叶子到根,代码是反得)
cout << "num:"<< i << " elem:" << elem[i] << //输出
" weight:" << HT[i].weight << " code:" << HC[i] << endl;
}
" weight:" << HT[i].weight << " code:" << HC[i] << endl;
}
free (cd); //释放空间
}
}
int main() {
HuffmanTree HT;
HuffmanCode HC;
int n,i;
HuffmanTree HT;
HuffmanCode HC;
int n,i;
cout << "Please input how many elements you have:";
cin >> n;
char elem[MAXSIZE]; //存储元素
int priority[MAXSIZE]; //存储权值
cin >> n;
char elem[MAXSIZE]; //存储元素
int priority[MAXSIZE]; //存储权值
for (i=1;i<=n;i++) { //输入
cout << "Please input your the " << i <<
"th element and its priority:";
cin >> elem[i];
cin >> priority[i-1];
}
cout << endl;
cout << "Please input your the " << i <<
"th element and its priority:";
cin >> elem[i];
cin >> priority[i-1];
}
cout << endl;
HuffmanCoding (HT,HC,priority,n,elem);
system ("pause");
return 0;
}
return 0;
}