#include#include #include #include #include //int n1 = 0, n2 = 0; #pragma warning(disable:4996) struct Huffunode//定义哈夫曼树结点 { int weight; int parent; int lchild; int rchild; }; void select(Huffunode huffutree[], int n, int& n1, int& n2)//定义返回数组两个最小值下标,由于用return只能返回一个值故可以使用引用或者全局变量或者结构体 { int a[1000];//将哈夫曼树中叶节点的权值拷贝到数组a中下标一致 for (int i = 0; i < n; i++) { a[i] = huffutree[i].weight; } //for(int i=0;i s1&&a[i] < s2&&huffutree[i].parent == -1)//若a[i]比s1大但是比s2小且该结点没有父亲结点parent域为-1则将s2的值改为a[i],n2的值改为i { s2 = a[i]; n2 = i; //printf("%d,%dn", n1, n2); } } } void createhuffmantree(Huffunode huffutree[], int w[], int n)//创建哈夫曼树 { for (int i = 0; i < 2 * n - 1; i++)//初始化,若叶子数为n则哈夫曼树结点数为2n-1. { huffutree[i].parent = -1; huffutree[i].lchild = -1; huffutree[i].rchild = -1; } for (int i = 0; i < n; i++)//给叶子结点赋权值 huffutree[i].weight = w[i]; for (int i = n; i < (2 * n) - 1; i++)//构建过程 { int n1 = 0, n2 = 0; select(huffutree, i, n1, n2);//选择已有哈夫曼树结点中两个权值最小且没有双亲的结点 //printf("%d %dn", n1, n2); huffutree[i].weight = huffutree[n1].weight + huffutree[n2].weight;//连接 huffutree[n1].parent = i; huffutree[n2].parent = i; huffutree[i].lchild = n1; huffutree[i].rchild = n2; //printf("%d %d %d %dn", huffutree[i].weight, huffutree[i].parent, huffutree[i].lchild, huffutree[i].rchild); } } void huffucoding(Huffunode huffutree[], char* huffunode[], int n)//哈夫曼树编码 { char *temp=(char*)malloc(sizeof(char)*n);//开辟一个长度为n的数组temp temp[n-1] = ' ';//将最后一个位置储存’ '结束符,方面用%s输出 for (int i = 0; i < n; i++) { int t = 0; int cur = n-1;//储存哈夫曼码位置 int pos = i;//当前处理结点 int parent = huffutree[i].parent;//当前结点的双亲结点 while (parent != -1)//如果当前结点有双亲则进入循环,从叶子到根逆向编码 { if (huffutree[parent].lchild ==pos)//当前结点是双亲结点的左孩子编码为0,否则编码为1 { temp[--cur] =' 0'; t++; } else if (huffutree[parent].rchild == pos) { temp[--cur] ='1'; t++; } pos = parent;//指向下一个结点 parent = huffutree[parent].parent; } //printf("%sn", &temp[cur]); huffunode[i] = (char*)malloc(sizeof(char)*(n - cur));//开辟哈夫曼编码长度的数组,并用指针数组的i个元素指向首地址 strncpy(huffunode[i], &temp[cur],n-cur);//将临时开辟temp指向的空间的值拷贝到huffunode[i]指向的区域 } free(temp);//释放临时开辟的空间 } int main()//测试 { Huffunode huffutree[1000]; char* huffunode[1000]; int w []={11,4,6,2,13,25,8,16 }; createhuffmantree(huffutree, w, 8); printf("哈夫曼树如下:n"); printf(" 权值 父亲结点序号 左孩子序号 右孩子序号n"); for (int i = 0; i < 15; i++) { printf("下标%2d: %3d %9d %12d %12dn",i, huffutree[i].weight, huffutree[i].parent, huffutree[i].lchild, huffutree[i].rchild); } huffucoding(huffutree,huffunode, 8); for (int i = 0; i < 8; i++) { printf(" %d:%sn",huffutree[i].weight, huffunode[i]); } }



