哈夫曼树源代码
c语言实现哈夫曼算法
c语言实现哈夫曼算法以下是C语言实现哈夫曼算法的示例代码:```cinclude <>include <>include <>// 定义哈夫曼树节点结构体typedef struct HuffmanNode {char data; // 节点存储的数据int freq; // 节点出现的频率struct HuffmanNode left, right; // 左右子树指针} HuffmanNode;// 定义创建哈夫曼树函数HuffmanNode createNode(char data, int freq) { HuffmanNode node =(HuffmanNode)malloc(sizeof(HuffmanNode));node->data = data;node->freq = freq;node->left = node->right = NULL;return node;}// 定义比较函数,用于按照频率从小到大排序int compare(const void a, const void b) {return ((HuffmanNode)b)->freq - ((HuffmanNode)a)->freq; }// 定义构建哈夫曼树函数HuffmanNode buildHuffmanTree(char data[], int freq[], int size) { if (size == 1) {return createNode(data[0], freq[0]);} else {HuffmanNode nodes[size]; // 存储所有节点指针的数组for (int i = 0; i < size; i++) {nodes[i] = createNode(data[i], freq[i]);}qsort(nodes, size, sizeof(HuffmanNode), compare); // 按频率从小到大排序return mergeNodes(nodes, size); // 合并两个最小的节点,直到只剩下一个节点}}// 定义合并两个最小节点函数HuffmanNode mergeNodes(HuffmanNode nodes[], int size) {if (size == 0) return NULL; // 空节点返回NULL指针if (size == 1) return nodes[0]; // 只剩下一个节点直接返回该节点指针 HuffmanNode root = createNode('$', nodes[0]->freq + nodes[1]->freq); // 创建根节点,频率为左右子树频率之和root->left = mergeNodes(nodes+1, size-1); // 递归合并剩余节点,左子树指向左子树数组中除第一个节点外的所有节点指针,右子树指向右子树数组中除最后一个节点外的所有节点指针return root; // 返回根节点指针}```。
哈夫曼编码器-源代码
#include <stdio.h>#include <string.h>#include <stdlib.h>typedef struct{char data;int weight;int parent;int lchild;int rchild;}HTNode;HTNode ht[30];typedef struct{char cd[30];int start;}HCode;HCode hcd[30];void CreateHT( HTNode ht[] , int n ) {int i , k , lnode, rnode ;int min1 , min2 ;for ( i = 0 ; i < 2*n-1 ; i++ ){ht[i].parent = ht[i].lchild = ht[i].rchild = 0;}for ( i = n ; i < 2*n-1 ; i++ ){min1 = min2 = 32767;lnode = rnode = 0;for ( k=0 ; k <= i-1; k++)if ( ht[k].parent == 0) {if (ht[k].weight < min1){min2 = min1;min1 = ht[k].weight;rnode = lnode;lnode = k;}else if ( ht[k].weight < min2){min2 = ht[k].weight;rnode = k;}}ht[lnode].parent = i;ht[rnode].parent = i;ht[i].weight = ht[lnode].weight + ht[rnode].weight;ht[i].lchild = lnode;ht[i].rchild = rnode;}}void CreateHCode( HTNode ht[] , HCode hcd[] , int n ){int i , f , c;HCode hc;for( i = 0 ; i < n; i++){hc.start = n;c = i;f = ht[i].parent;while (f != 0){if( ht[f].lchild == c){hc.cd[hc.start--] = '0';}else{hc.cd[hc.start--] = '1';}c=f ;f=ht[f].parent;}hc.start++;hcd[i] = hc;}}void CodeInput(int n,HTNode ht[]){int i;char ch[30];scanf( "%s" , ch );for ( i=0 ; i<n ; i++ ){scanf( "%ld" , &ht[i].weight );}printf("######################################- \n"); }void CodeOutput( int n , HCode hcd[] ){int i , j ;printf (" 所有字符的哈弗曼编码为:");for ( i = 0 ; i < n ; i++ ){for( j=hcd[i].start ; j<=n ; j++ ){printf( "%lc" , hcd[i].cd[j] );}}printf("\n");for ( i=0 ; i<n ; i++ ){printf( " 序号%d : " , i );for( j = hcd[i].start ; j <= n ; j++ ){printf( "%lc" , hcd[i].cd[j] );}printf( "\n" );}}void save( int n ){int i ;FILE *fp;if( ( fp = fopen ( "c:\\data.txt" , "w" ) ) == NULL ) {printf( " can't open this file !!! " ) ;exit(0) ;}else{for ( i = 1 ; i <= n ; i++ ){fprintf( fp , " %ld ", ht[i].weight );}printf(" You have saved it successful !!!");}fclose (fp) ;}void main(){ int num ;char flag ='y';while( flag == 'y' || flag == 'Y' ){system( "cls" );printf(" ################################ \n");printf(" 欢迎使用哈夫曼编码系统\n ");printf(" ################################ \n");printf(" ######## 1. 生成哈夫曼树#########\n");printf(" ######### 2. 哈夫曼编码######### \n");printf(" ######### 3.哈夫曼权值存储######### \n");printf(" ######## 4. 退出########\n");printf(" ##############################\n");printf(" 请选择操作类型( 1 - 4 ) : " );scanf( " %d" , &num );printf("############################################ \n");switch(num){case 1 :int n , i ;printf(" 请输入要输入的字符数量n为: ");if((scanf(" %ld", &n ))&&(n!=0)){printf("\n 请输入%d 个字符和%d 个对应权值<先将所有字符输入再输对应权值> \n 在此输入: " , n , n );CodeInput( n , ht );CreateHT( ht , n );printf(" 对应的权值为:\n");for( i = 0 ; i < n ; i++ ){printf( " %d : %ld " , i , ht[i].weight );if((i+1) % 4 == 0){printf("\n");}}}printf("\n######################################- \n");break;case 2 :CreateHCode( ht , hcd , n );CodeOutput( n , hcd );printf("##############################################-");break;case 3 :save(n);printf("#######################################");break;case 4 :printf("############# **感谢使用本程序** ############### \n ");exit(1);printf("########################################");break;default :printf(" Error ! You must put the number between <1 -- 4> ");printf("\n#####################################\n");}printf(" \n 继续或退出(y or n) : ");getchar() ;flag=getchar();}}。
哈夫曼树的构造c语言代码
哈夫曼树的构造c语言代码哈夫曼树是一种特殊的二叉树,常被用于数据压缩中。
它的构造过程非常重要,接下来我将用c语言展示如何构造哈夫曼树。
首先,我们需要定义一个结构体作为节点:```struct Node{int weight;//权重int parent;//父节点在数组中的下标int lchild;//左子节点在数组中的下标int rchild;//右子节点在数组中的下标};```然后,我们需要读入数据,计算每个数据的权重,随后用一个数组存储节点信息:```int n;//数据个数int W[maxn];//存储每个数据的权重Node tree[maxn*2-1];//哈夫曼树```接下来,我们需要编写一个函数用来选择权值最小的两个节点,然后将它们合并成一个节点。
```int select_min(Node*tree,int n){int res=-1;int min=INT_MAX;for(int i=0;i<n;i++){if(tree[i].parent!=-1)continue;//跳过已经合并的节点if(tree[i].weight<min){min=tree[i].weight;res=i;}}return res;}void merge_node(Node*tree,int a,int b,int i){tree[a].parent=i;tree[b].parent=i;tree[i].weight=tree[a].weight+tree[b].weight;tree[i].lchild=a;tree[i].rchild=b;}```接下来,我们就可以开始构造哈夫曼树了。
我们先初始化每个节点,将它们都看成一个独立的树,然后选择最小的两个节点进行合并,直到最后只剩下一个树为止。
```void build_tree(Node*tree,int n,int*W){for(int i=0;i<n;i++){tree[i].weight=W[i];tree[i].parent=-1;tree[i].lchild=-1;tree[i].rchild=-1;}for(int i=n;i<(n<<1)-1;i++) {int a=select_min(tree,i);int b=select_min(tree,i);merge_node(tree,a,b,i);}}```最后,我们可以调用build_tree函数来构造哈夫曼树。
二叉树,哈夫曼树典型问题源代码
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>#define MAXSIZE 100#define QUEUE_MAXSIZE 50typedef char DATA;typedef struct//哈夫曼树{int weight;int parent;int lchild;int rchild;}HTNode;typedef char * HCode;//哈夫曼编码void SelectNode(HTNode *ht,int n,int *bt1,int *bt2)//找出两个最小的数作为子左右节点{int i;HTNode *ht1,*ht2,*t;ht1=ht2=NULL;//初始化两个结点为空for(i=0;i<=n;i++){if(!ht[i].parent)//父结点设置为空(结点的parent=0){if(ht1==NULL){ht1=ht+i;//指向第i个结点continue;//继续循环}if(ht2==NULL)//结点指针2为空{ht2=ht+i;//指向第i个结点if(ht1->weight>ht2->weight)//比较结点权重{t=ht2;//使h2指向结点权值为次小的结点ht2=ht1;//使h1指向结点权值为最小的结点ht1=t;}continue;//继续循环}if(ht1 && ht2)//h1和h2都有效{if(ht[i].weight<=ht1->weight)//第i个结点的权重小于h1指向结点的权重{ht2=ht1;ht1=ht+i;}else if(ht[i].weight<ht2->weight){ht2=ht+i;}}}}if(ht1>ht2)//增加比较,使二叉树左侧为叶节点{*bt2=ht1-ht;*bt1=ht2-ht;}else{*bt1=ht1-ht;*bt2=ht2-ht;}}void CreateTree(HTNode *ht,int n,int * w)//建立哈夫曼树{int i,m=2*n-1;//总结点数int bt1,bt2;//二叉树节点序号if(n<=1)return ;//只有一个结点无法创建for(i=1;i<=n;++i){ht[i].weight=w[i-1];ht[i].parent=0;ht[i].lchild=0;ht[i].rchild=0;}for(;i<=m;i++)//初始化后续结点{ht[i].weight=0;ht[i].parent=0;ht[i].lchild=0;ht[i].rchild=0;}for(i=n+1;i<=m;i++)//逐个计算非叶结点,创建哈夫曼树{SelectNode(ht,i-1,&bt1,&bt2);//调用函数得到权值最小的两个结点ht[bt1].parent=i;//设置两个结点的父结点ht[bt2].parent=i;ht[i].lchild=bt1;ht[i].rchild=bt2;ht[i].weight=ht[bt1].weight+ht[bt2].weight;//在父结点中保存权值}}void HCoding(HTNode * ht,int n,HCode * hc)//哈夫曼编码{char * cd;int start,i;int current,parent;cd=(char*)malloc(sizeof(char)*n);//用来临时存放一个字符编码的结果cd[n-1]='\0';//设置字符串接鼠标指for(i=1;i<=n;i++){start=n-1;current=i;parent=ht[current].parent;//获取当前父结点while(parent)//父结点不空{if(current==ht[parent].lchild)//该结点是父结点的左子树cd[--start]='0';//编码为0elsecd[--start]='1';//该结点是父结点的右子树,编码为1current=parent;//设置当前节点值相符结点parent=ht[parent].parent;//获取当前节点的父亲结点序号}hc[i-1]=(char*)malloc(sizeof(char)*(n-start));//分配保存编码的内存strcpy(hc[i-1],&cd[start]);//复制生成的编码}free(cd);//释放空间}typedef struct ChainTree //定义二叉树结点类型{DATA data;struct ChainTree *left;//左孩子struct ChainTree *right;//右孩子int rtag;//标志位rtag标志是否为链表指针int flag1;//标志位flag1}ChainBinTree;void oper(ChainBinTree *p){printf("%c ",p->data); //输出数据}ChainBinTree * BinTreeInit(ChainBinTree *node) //初始化二叉树根结点{if(node!=NULL) //若二叉树根结点不为空return node;elsereturn NULL;}int BinTreeAddNode(ChainBinTree *bt,ChainBinTree *node,int n) //添加数据到二叉树//bt为父结点,node为子结点,n=1表示添加左子树,n=2表示添加右子树{if(bt==NULL){printf("父结点不存在,请先设置父结点!\n");return 0;}switch(n){case 1: //添加到左结点if(bt->left) //左子树不为空{printf("左子树结点不为空!\n");return 0;}elsebt->left=node;break;case 2://添加到右结点if( bt->right) //右子树不为空{printf("右子树结点不为空!\n");return 0;}elsebt->right=node;break;default:printf("参数错误!\n");return 0;return 1;}ChainBinTree *BinTreeFind(ChainBinTree *bt,DATA data) //在二叉树中查找值为data的结点{ChainBinTree *p;if(bt==NULL)return NULL;else{if(bt->data==data)return bt;else{ //分别向左右递归查找if(p=BinTreeFind(bt->left,data))return p;else if(p=BinTreeFind(bt->right, data))return p;elsereturn NULL;}}}void BinTree_DLR(ChainBinTree *bt) //先序遍历{if(bt){oper(bt); //输出先序遍历BinTree_DLR(bt->left);//先序递归调用左子树BinTree_DLR(bt->right);//先序递归调用右子树}}void BinTree_LDR(ChainBinTree *bt) //中序遍历{if(bt){BinTree_LDR(bt->left);oper(bt);BinTree_LDR(bt->right);}void BinTree_LRD(ChainBinTree *bt) //后序遍历{if(bt){BinTree_LRD(bt->left);BinTree_LRD(bt->right);oper(bt);}}ChainBinTree *InitRoot() //初始化二叉树的根{ChainBinTree *node;if(node=(ChainBinTree *)malloc(sizeof(ChainBinTree)))//分配内存 {printf("\n输入根结点数据:");scanf("%s",&node->data);node->left=NULL;//设置左右子树为空node->right=NULL;return BinTreeInit(node);//返回根结点}return NULL;}void AddNode(ChainBinTree *bt)//添加节点{ChainBinTree *node,*parent;DATA data;char select;if(node=(ChainBinTree *)malloc(sizeof(ChainBinTree)))//分配内存 {printf("\n输入二叉树结点数据:");scanf("%s",&node->data);node->left=NULL; //设置左右子树为空node->right=NULL;printf("输入父结点数据:");scanf("%s",&data);parent=BinTreeFind(bt,data);//查找指定数据的结点if(!parent){printf("未找到父结点!\n");free(node);}printf("1.添加到左子树\n2.添加到右子树\n");do{scanf("%c",&select);select-='0';if(select==1 || select==2)BinTreeAddNode(parent,node,select);}while(select!=1 && select!=2);}}ChainBinTree *pre=NULL; //外部变量pre置NULLint flag=1;void ChangeList(ChainBinTree * bt)//将二叉树的子节点转化为链表{ChainBinTree * head;if(bt){ChangeList(bt->left);//中序遍历将叶子结点转化为线性链表if(bt->left==NULL&&bt->right==NULL&&flag==1)//头结点指向第一个叶子节点{head=bt;flag++;//标志位pre=bt;bt->rtag=1;printf("%c",bt->data);}else if(bt->left==NULL&&bt->right==NULL&&flag!=1)//判断是否为叶子节点{pre->right=bt;pre=bt;bt->right=NULL;bt->rtag=1;//标志位rtag判断右孩子的属性printf("%c",bt->data);}elsebt->rtag=0;//标志位置零ChangeList(bt->right);}}void Find_Ancient(ChainBinTree *root,DATA data)//找到data所有的祖先结点{ChainBinTree * p, * node[MAXSIZE];//node[]起到栈的作用int top=0,i,tag[100]; p=root;//栈顶topwhile(p!=NULL||top!=0)//非递归后续遍历找到结点数据为data的结点{while(p){top++;node[top]=p;//子树根节点进栈tag[top]=0;p=p->left;}while(top>0 && tag[top]==1){p=node[top];if(p->data==data)//找到节点数据为data的数据{for(i=top-1;i>0;i--){printf("%c ",node[i]->data);//将栈中全部数据出栈}printf("\n");p=NULL;top=1;//清空栈跳出循环}top--;}if(top>0){p=node[top];tag[top]=1;p=p->right;}elsep=NULL;//置p=null}}void BinTree_Level(ChainBinTree *bt) //按层遍历{ChainBinTree *p;ChainBinTree *q[QUEUE_MAXSIZE]; //定义一个顺序栈int head=0,tail=0;//队首、队尾序号if(bt)//若队首指针不为空{tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列队尾序号q[tail] = bt;//将二叉树根指针进队}while(head!=tail) //队列不为空,进行循环{head=(head+1)%QUEUE_MAXSIZE; //计算循环队列的队首序号p=q[head]; //获取队首元素if(p->left!=NULL) //若结点存在左子树,则左子树指针进队{tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列的队尾序号q[tail]=p->left;//将左子树指针进队}if(p->right!=NULL)//若结点存在右孩子,则右孩子结点指针进队{tail=(tail+1)%QUEUE_MAXSIZE;//计算循环队列的队尾序号q[tail]=p->right;//将右子树指针进队}if(p->left==NULL&&p->right!=NULL){printf("不是完全二叉树!\n");break; }}if(head==tail){printf("是完全二叉树!\n");}}void print(ChainBinTree * bt)//打印树{if(bt!=NULL){printf("%c",bt->data);if(bt->left!=NULL||bt->right!=NULL){printf("(");print(bt->left);if(bt->right!=NULL)printf(",");print(bt->right);printf(")");}}}void Del_subtree(ChainBinTree * bt){//删除bt所指二叉树,并释放相应的空间if (bt){Del_subtree(bt->left);Del_subtree(bt->right);free(bt);}}//Del-subtreevoid Search_Del(ChainBinTree * bt, DATA x){//在bt所指的二叉树中,查找所有元素值为x的结点,并删除以它为根的子树if (bt){if (bt->data==x)//找到该数据的节点{print(bt);//打印Del_subtree(bt);//清空子树}else{Search_Del(bt->left, x);//递归调用左子树查询并删除数据为x的结点Search_Del(bt->right, x);//递归调用右子树查询并删除数据为x的结点}}}int main(){ChainBinTree *root=NULL,* head=NULL; //root为指向二叉树根结点的指针int i,n=6,j=1,m,flag=0,w[100];m=2*n-1;char alphabet[]={'A','B','C','D','E','F'};//哈夫曼树字母表char select;HTNode * ht;//哈夫曼树指针HCode * hc;//哈夫曼编码指针ht=(HTNode *)malloc((m+1)*sizeof(HTNode));//分配空间if(!ht){printf("分配内存失败\n");}hc=(HCode *)malloc(n*sizeof(char *));//分配空间if(!hc){printf("分配内存失败\n");}do{printf("*******************************************\n");//打印主菜单printf("1.设置二叉树根元素 2.添加二叉树结点\n");//主菜单功能printf("3.先序遍历 4.中序遍历\n");printf("5.后序遍历 6.把叶子结点转化为单链表:\n" );printf("7.判断完全二叉树: 8.查找节点并打印其祖先结点:\n");printf("9.哈夫曼编码: 0.删除所有以结点x(x为结点元素值)为根的子树 \n");printf("!.退出\n");printf("*******************************************\n");select=getch();//获取字符,并执行对应命令switch(select){case '1':root=InitRoot();//初始化根节点break;case '2':AddNode(root);//添加节点break;case '3':printf("\n先序遍历的结果:");//先序遍历BinTree_DLR(root);printf("\n");break;case '4':printf("\n中序遍历的结果:");//中序遍历BinTree_LDR(root);printf("\n");break;case '5':printf("\n后序遍历的结果:");//后序遍历BinTree_LRD(root);printf("\n");break;case '6':printf("叶子节点转化为链表后结果为:\n");//叶子节点转化为链表 ChangeList(root);printf("\n先序遍历的结果:");BinTree_DLR(root);printf("\n");break;case '7':BinTree_Level(root);//层序遍历并判断是否是完全二叉树break;case '8':if(root){if(BinTreeFind(root,'e')!=NULL)//打印字符e的所有祖先{printf("找到该节点,该节点的所有祖先为:\n");Find_Ancient(root,'e');}elseprintf("无此节点!\n");}break;case '9':printf("输入(A-F)字母的权重:\n"); //对字母表进行哈夫曼编码 for(i=0;i<n;i++){printf("%c:",65+i);scanf("%d",w+i);printf("\n");}CreateTree(ht,n,w);//创建哈夫曼树HCoding(ht,n,hc);//创建哈夫曼编码for(i=1;i<=n;i++)printf("字母:%c,权重:%d,编码为:%s\n",alphabet[i-1],ht[i].weight,hc[i-1]);break;case'0':Search_Del(root,'c');//查找并删除结点x子树break;case'!':break;default:printf("输入错误,请重新输入!\n");//输入错误相关问题break;}}while(select!='!');//!则结束程序getch();//获取字符system("pause");return 0;}。
哈夫曼树编码c语言
以下是C语言实现哈夫曼树编码的示例代码:```c#include <stdio.h>#include <stdlib.h>// 定义结构体表示节点struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;};// 创建新节点struct TreeNode* newNode(int val) {struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));node->val = val;node->left = NULL;node->right = NULL;return node;}// 计算权值和int calculateWeightSum(struct TreeNode* root) {if (root == NULL) {return 0;}return root->val + calculateWeightSum(root->left) + calculateWeightSum(root->right);}// 构建哈夫曼树struct TreeNode* buildHuffmanTree(int** freq, int size) {// 创建频率数组int arr[size];for (int i = 0; i < size; i++) {arr[i] = freq[i][0];}// 构建哈夫曼树struct TreeNode* root = NULL;int index = 0;while (index < size) {int min1 = INT_MAX, min2 = INT_MAX;int min1Index = -1, min2Index = -1;for (int i = 0; i < size; i++) {if (arr[i] < min1 && arr[i] != 0) {min1 = arr[i];min1Index = i;}if (arr[i] < min2 && arr[i] != 0) {min2 = arr[i];min2Index = i;}}// 创建新节点作为左右子树,并加入频率数组中arr[min1Index] = 0;arr[min2Index] = 0;struct TreeNode* left = newNode(min1);struct TreeNode* right = newNode(min2);left->left = right;right->right = left;// 将左右子树作为新的根节点,并更新频率数组和根节点指针if (root == NULL) {root = left;} else {struct TreeNode* parent = root;while (parent->left != NULL) {parent = parent->left;}parent->left = left;left->parent = parent;while (parent->right != NULL) {parent = parent->right;}parent->right = right;right->parent = parent;}index += 2; // 跳过左右子树,继续寻找下一对最小的节点构建子树,直到遍历完所有节点为止。
赫夫曼树源代码
//创建哈夫曼树#include<stdio.h>#include<string.h>typedef struct{unsigned weight;int parent;int lchild;int rchild;}HTNode,*HuffmanTree;int min(HuffmanTree &p,int m){ unsigned int t=32768;int flag;for(int i=1; i<=m; i++){if(p[i].weight<t &&p[i].parent==0){t=p[i].weight;flag=i;}}p[flag].parent=1;//--m;printf("\nflag=%d\n\n",flag);return flag;}void select(HuffmanTree &T,int m,int &s1,int &s2){ //这里的m=i-1;比如i=n+1的时候,就是从1到n的序号中选择s1,s2 int temp;s1=min(T,m);s2=min(T,m);if(s1>s2){temp=s1;s1=s2;s2=temp;}}int HuffmanCoding(HuffmanTree &T,char ** &HC,int w[],int n){int s1;int s2;int m=2*n-1;T=new HTNode [m+1];if(n<=1) return 0;HTNode *p;int i;for( i=1,p=T+1; i<=n; ++i,++p)//注意p是一级指针,HT是二级指针{printf("%d\n",w[i]);p->weight=w[i];p->parent=0;p->lchild=0;p->rchild=0;}/*for(int i=1; i<=n; i++){T[i].weight=w[i-1];T[i].parent=0;t[i].lchild=0;t[i].rchlid=0;}*/for(; i<=m; ++i,++p){p->weight=0;p->parent=0;p->lchild=0;p->rchild=0;}printf("\n\n");for (i=n+1; i<=m; ++i){select(T,i-1,s1,s2);printf("\ns1=%ds2=%d\n\n\n",s1,s2);T[i].lchild=s1;T[i].rchild=s2;T[i].weight=T[s1].weight+T[s2].weight;T[s1].parent=i;T[s2].parent=i;}//求所有叶子节点的编码int start;unsigned int c,f;char *cd;HC=new char *[n+1];//HC是二级指针,cd=new char [n];//每个叶子节点的编码的最大长度为n for(i=1; i<=n; i++){start=n-1;cd[n-1]='\0';//for(c=i,f=T[i].parent; f!=0; c=f,f=T[f].parent){if (T[f].lchild==c)//if(c==f.lchild) 错误之处cd[--start]='0';else cd[--start]='1';}HC[i]=new char[n-start];strcpy(HC[i],&cd[start]);}delete [] cd;for(i=1; i<=n; i++){printf(" %d的编码是:%s\n",i,HC[i]);}}int main(){HuffmanTree T;char **HC;int n;printf("请输入叶子总数\n");scanf("%d",&n);int *w;printf("geejieidnade quanzhong\n");w=new int [n+1];for(int i=1; i<=n; i++)scanf("%d",w+i);HuffmanCoding(T,HC,w,n);return 0;}。
哈弗曼编码源代码
x2=j; } } huff_node[x1].parent=n+i; //将找出的两棵树合并为一颗子树 huff_node[x2].parent=n+i; huff_node[x1].flag=1; huff_node[x2].flag=1; huff_node[n+i].weight=huff_node[x1].weight+huff_node[x2].weight; huff_node[n+i].lchild=x1; huff_node[n+i].rchild=x2; } for(i=0;i<n;i++) //求哈弗曼编码 { cd.start=n; //哈弗吗编码存放在从cd.start到 n的分量上 c=i; p=huff_node[c].parent; while(p!=-1) { if(huff_node[p].lchild==c) cd.bits[cd.start]=0; else cd.bits[cd.start]=1; cd.start=cd.start-1; c=p; p=huff_node[p].parent; } for(j=cd.start+1;j<=n;j++) huff_code[i].bits[j]=cd.bits[j]; huff_code[i].start=cd.start; } fp=fopen("file.txt","w"); if(fp==NULL)
数据结构哈夫曼树的代码
数据结构哈夫曼树的代码数据结构哈夫曼树的代码实现:1·简介哈夫曼树(Huffman Tree),又称为最优二叉树,是一种用于数据压缩的树形结构。
它利用出现频率较高的字符采用较短的编码,而出现频率较低的字符采用较长的编码,从而实现数据的压缩和解压缩。
本文将详细介绍哈夫曼树的构建和编码解码的过程。
2·哈夫曼树的构建2·1 核心思想哈夫曼树的构建核心思想是根据字符的出现频率构建一棵树,使得频率高的字符离树根近,频率低的字符离树根远。
构建哈夫曼树的步骤如下:●创建一个包含所有字符的叶子结点集合。
●从集合中选择两个频率最低的结点(注意:频率越低,优先级越高),构建一个新的二叉树,根节点的频率等于这两个结点的频率之和。
●将新构建的二叉树的根节点加入集合中。
●重复上述操作,直到集合中只剩一个根结点,即构建完成。
2·2 代码实现下面是一个示例的哈夫曼树构建的代码:```pythonclass Node:def __init__(self, freq, char=None):self·freq = freqself·char = charself·left = Noneself·right = Nonedef build_huffman_tree(char_freq):leaves = [Node(freq, char) for char, freq in char_freq·items()]while len(leaves) > 1:leaves·sort(key=lambda x: x·freq)left = leaves·pop(0)right = leaves·pop(0)parent = Node(left·freq + right·freq)parent·left = leftparent·right = rightleaves·append(parent)return leaves[0]```3·哈夫曼树的编码3·1 核心思想哈夫曼树的编码过程是根据构建好的哈夫曼树,对每个字符进行编码。
c语言实现构造哈夫曼树代码
c语言实现构造哈夫曼树代码一、哈夫曼树简介哈夫曼树是一种特殊的二叉树,其每个叶子节点都对应一个权值,而非叶子节点则没有权值。
哈夫曼树的构造过程中,将权值较小的节点放在左子树,权值较大的节点放在右子树,这使得哈夫曼树的带权路径最短。
哈夫曼编码就是利用这种特性实现对数据进行压缩。
二、C语言实现构造哈夫曼树1. 定义结构体首先需要定义一个结构体来表示哈夫曼树中的节点。
结构体中包含了该节点的权值以及指向左右子节点的指针。
```typedef struct TreeNode {int weight;struct TreeNode *left;struct TreeNode *right;} TreeNode;2. 构造哈夫曼树接下来需要实现构造哈夫曼树的函数。
该函数接收一个数组作为输入,数组中存储了每个叶子节点的权值。
首先需要将数组中所有元素转化为TreeNode类型,并将它们存储在一个链表中。
```TreeNode *createTreeNodes(int weights[], int size) {TreeNode *nodes[size];for (int i = 0; i < size; i++) {nodes[i] = (TreeNode *)malloc(sizeof(TreeNode));nodes[i]->weight = weights[i];nodes[i]->left = NULL;nodes[i]->right = NULL;}return nodes;}```接下来,需要实现一个函数来找到权值最小的两个节点。
该函数接收一个链表作为输入,并返回该链表中权值最小的两个节点。
```void findMinNodes(TreeNode **nodes, int size, TreeNode**minNode1, TreeNode **minNode2) {*minNode1 = *minNode2 = NULL;for (int i = 0; i < size; i++) {if (*minNode1 == NULL || (*nodes)[i].weight <(*minNode1)->weight) {*minNode2 = *minNode1;*minNode1 = &(*nodes)[i];} else if (*minNode2 == NULL || (*nodes)[i].weight < (*minNode2)->weight) {*minNode2 = &(*nodes)[i];}}}```接下来,需要实现一个函数来构造哈夫曼树。
哈夫曼树python实现
哈夫曼树python实现哈夫曼树(Huffman Tree)是一种用于数据压缩的树形结构,通过对字符出现频率的统计,构建出具有最小加权路径长度的树,从而实现高效的压缩编码。
下面是一个使用 Python 实现哈夫曼树的示例代码:```python# 定义节点类class Node:def __init__(self, char, freq):self.char = charself.freq = freqself.left = Noneself.right = Noneself.parent = None# 定义哈夫曼树类class HuffmanTree:def __init__(self):self.nodes = {}self.root = None# 插入节点def insert(self, char, freq):if char in self.nodes:self.nodes[char].freq += freqelse:node = Node(char, freq)self.nodes[char] = node# 构建哈夫曼树def build_tree(self):nodes = list(self.nodes.values())nodes.sort(key=lambda x: x.freq, reverse=True) while len(nodes) > 1:# 找到两个频率最小的节点left, right = nodes[0], nodes[1]node = Node(None, left.freq + right.freq) node.left = leftnode.right = rightleft.parent = noderight.parent = nodenodes.remove(left)nodes.remove(right)nodes.append(node)self.root = nodes[0]# 编码def编码(self, text):code = ""node = self.rootfor char in text:while node.char!= char:if node.left is None:code += "0"node = node.rightelse:code += "1"node = node.leftcode += node.charnode = node.parentreturn code# 示例用法ht = HuffmanTree()ht.insert('a', 45)ht.insert('b', 13)ht.insert('c', 12)ht.insert('d', 23)ht.insert('e', 34)ht.build_tree()text = "abe"encoded_text = ht编码(text)print("Encoded text:", encoded_text)```在上述示例中,我们定义了节点类 `Node` 用于表示哈夫曼树中的节点,以及哈夫曼树类 `HuffmanTree`。
用c++写哈夫曼编码
用c++写哈夫曼编码以下是使用C++实现哈夫曼编码的示例代码:c复制代码#include<iostream>#include<queue>#include<string>#include<vector>using namespace std;struct TreeNode {char data;int freq;TreeNode *left, *right;TreeNode(char data, int freq) : data(data), freq(freq), left(NULL), right(NULL) {}};struct cmp {bool operator()(const TreeNode *a, const TreeNode *b) {return a->freq > b->freq;}};void printCodes(TreeNode *root, string code) {if (root == NULL) {return;}if (root->left == NULL && root->right == NULL) {cout << root->data << ": " << code << endl;return;}printCodes(root->left, code + "0");printCodes(root->right, code + "1");}void buildHuffmanTree(const vector<char>& data, const vector<int>& freq) { priority_queue<TreeNode*, vector<TreeNode*>, cmp> pq;for (int i = 0; i < data.size(); i++) {pq.push(new TreeNode(data[i], freq[i]));}while (pq.size() > 1) {TreeNode *left = pq.top();pq.pop();TreeNode *right = pq.top();pq.pop();TreeNode *top = new TreeNode('$', left->freq + right->freq);top->left = left;top->right = right;pq.push(top);}TreeNode *root = pq.top();pq.pop();printCodes(root, "");}int main() {vector<char> data = {'a', 'b', 'c', 'd', 'e', 'f'};vector<int> freq = {5, 9, 12, 13, 16, 45};buildHuffmanTree(data, freq);return0;}在这个示例中,我们首先定义了一个结构体TreeNode,表示哈夫曼树的节点。
哈夫曼编码生成程序
#include <stdio.h>#include <stdlib.h>#define MaxSize 50typedef struct{char c; //代码;int w; //代码权值;char code[MaxSize]; //代码的Huffman编码;}HuffCode[MaxSize];typedef struct{int Weight; //权值;int LChild,RChild,Parent;}HTNode,HuffTree[MaxSize];//===================================================================== ===========void HuffmanTree(HuffTree HT,int length,HuffCode hc); //生成Huffman树;void SelectHTNode(HuffTree HT,int n,int *min1,int *min2); //查找最小和次小序号;void HuffmanCode(HuffTree HT,int len,HuffCode hc); //生成Huffman编码;//===================================================================== ===========int main(void){HuffTree HT; //Huffman树;HuffCode HC; //Huffman编码;int i,len;printf("<<<< Huffman编码生成程序>>>>\t\tby Haroldi.\n\n\n\n\n\n");printf("\n输入代码数量:"); scanf("%d",&len); system("cls");printf("代码数量:%2d\n\n",len);printf("输入代码及权值(e.g.: \"a16[回车]\" ):\n");for(i=1;i <= len;i++){while(getchar() != '\n') NULL;printf("No.%2d:",i);HC[i].c = getchar();scanf("%d",&HC[i].w);}HuffmanTree(HT,len,HC);HuffmanCode(HT,len,HC);printf("\n输出Huffman编码:\n");for(i = 1;i<=len;i++){printf("\n %c :",HC[i].c);puts(HC[i].code);}//测试Huffman树结构;printf("\n\n输出Huffman树结构:");system("pause");printf("\nHT[i]:\t权值\t双亲\t左孩子\t右孩子\n");for(i = 1;i<2*len;i++){if(i <= len) printf("(%c)",HC[i].c);printf("%2d,\t %2d,\t %2d,\t %2d,\t %2d\n",i,HT[i].Weight,HT[i].Parent,HT[i].LChild,HT[i].RChild);}return 0;}void HuffmanTree(HuffTree HT,int length,HuffCode hc) //Huffman树初始化;{int i,min1,min2;HT[0].Weight = 65535;for(i = 1;i <= length;i++){HT[i].Weight = hc[i].w;HT[i].LChild = HT[i].RChild = HT[i].Parent = -1;}for(;i < 2*length;i++) //i初值= length+1;{HT[i].LChild = HT[i].RChild = HT[i].Parent = -1;}for(i = length+1;i < 2*length;i++){SelectHTNode(HT,i,&min1,&min2);HT[min1].Parent = i;HT[min2].Parent = i;HT[i].LChild = min1;HT[i].RChild = min2;HT[i].Weight = HT[min1].Weight + HT[min2].Weight;}}//===================================================================== ===========void SelectHTNode(HuffTree HT,int n,int *min1,int *min2) //查找最小和次小序号;{int i;*min1 = *min2 = 0;for(i = 1;i < n;i++){if(HT[i].Parent == -1){if(HT[*min1].Weight >= HT[i].Weight){*min2 = *min1;*min1 = i;}else if(HT[*min2].Weight > HT[i].Weight) *min2 = i;}}}//===================================================================== ===========void HuffmanCode(HuffTree HT,int len,HuffCode hc) //生成Huffman编码;{int i,j,tc,Stack[MaxSize],top = -1;char flag[MaxSize];HTNode th;for(i = 1;i <= len;i++){top = -1; //栈初始化;j = 0; //hc[i].code串首位置偏移;th = HT[i]; //当前结点th;tc = i; //当前结点标记tc;while(th.Parent != -1){ //当前结点th双亲P入栈,由P的孩子是th,确定flag;确定下次结点标记tc;Stack[++top] = th.Parent;if(HT[th.Parent].LChild == tc) {flag[top] = 'L'; tc = th.Parent;}if(HT[th.Parent].RChild == tc) {flag[top] = 'R'; tc = th.Parent;}th = HT[Stack[top]]; //下一结点;}while(top != -1){if(flag[top] == 'L') hc[i].code[j++] ='0';else hc[i].code[j++] ='1';Stack[top--]; //出栈;}hc[i].code[j] ='\0'; //当前串结束;}}哈夫曼树在一般的数据结构的书中,树的那章后面,著者一般都会介绍一下哈夫曼(HUFFMAN)树和哈夫曼编码。
贪心哈夫曼编码c语言源代码
贪心哈夫曼编码c语言源代码贪心哈夫曼编码是一种常用的数据压缩算法,可以将数据压缩为更小的体积,提高传输效率。
在贪心哈夫曼编码中,每个字符都有一个对应的编码,而且这些编码是唯一的。
在编码时,我们需要构建一个哈夫曼树来确定每个字符的权值和编码方式。
然后,我们通过遍历哈夫曼树来生成每个字符的编码。
以下是一个使用C语言实现贪心哈夫曼编码的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_TREE_HT 100struct MinHeapNode {char data;unsigned freq;struct MinHeapNode *left, *right;};struct MinHeap {unsigned size;unsigned capacity;struct MinHeapNode **array;};struct MinHeapNode* newNode(char data, unsigned freq) {struct MinHeapNode* temp = (structMinHeapNode*)malloc(sizeof(struct MinHeapNode));temp->left = temp->right = NULL;temp->data = data;temp->freq = freq;return temp;}struct MinHeap* createMinHeap(unsigned capacity) {struct MinHeap* minHeap = (structMinHeap*)malloc(sizeof(struct MinHeap));minHeap->size = 0;minHeap->capacity = capacity;minHeap->array = (struct MinHeapNode**)malloc(minHeap->capacity * sizeof(struct MinHeapNode*));return minHeap;}void swapMinheapNodes(struct MinHeapNode** a, struct MinHeapNode** b) {struct MinHeapNode* t = *a;*a = *b;*b = t;}void minHeapify(struct MinHeap* minHeap, int idx) {int smallest = idx;int left = 2 * idx + 1;int right = 2 * idx + 2;if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)smallest = left;if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)smallest = right;if (smallest != idx) {swapMinheapNodes(&minHeap->array[smallest],&minHeap->array[idx]);minHeapify(minHeap, smallest);}}int isSizeOne(struct MinHeap* minHeap) {return (minHeap->size == 1);}struct MinHeapNode* extractMin(struct MinHeap* minHeap) { struct MinHeapNode* temp = minHeap->array[0];minHeap->array[0] = minHeap->array[minHeap->size - 1];--minHeap->size;minHeapify(minHeap, 0);return temp;}void insertMinheap(struct Minheap* minheap, struct MinheapNode* node) {++minheap->size;int i = minheap->size - 1;while (i && node->freq < minheap->array[(i - 1) / 2]->freq) { minheap> array[i] = heap- > array[(i - 1) / 2];i = (i - 1) / 2;}minheap->array[i] = node;}void buildMinHeap(struct MinHeap* minHeap) {int n = minHeap->size - 1;int i;for (i = (n - 1) / 2; i >= 0; --i)minHeapify(minHeap, i);}int isLeaf(struct MinHeapNode* root) {return !(root->left) && !(root->right);}struct MinHeap* createAndBuildMinheap(char data[], int freq[], int size) {struct MinHeap* minheap = createMinheap(size);for (int i = 0; i < size; ++i)minheap->array[i] = newNode(data[i], freq[i]);minheap->size = size;buildMinheap(minheap);return minheap;}struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size) {struct MinHeapNode *left, *right, *top;struct MinHeap* minheap = createAndBuildMinheap(data, freq, size);while (!isSizeOne(minheap)) {left = extractMin(minheap);right = extractMin(minheap);top = newNode('$', left->freq + right->freq);top->left = left;top->right = right;insertMinheap(minheap, top);}return extractMin(minheap);}void printCodes(struct MinHeapNode* root, int arr[], int top) { if (root->left) {arr[top] = 0;printCodes(root->left, arr, top + 1);}if (root->right) {arr[top] = 1;printCodes(root->right, arr, top + 1);}if (isLeaf(root)) {printf("%c: ", root->data);for (int i = 0; i < top; ++i)printf("%d", arr[i]);printf("\n");}}void HuffmanCodes(char data[], int freq[], int size) {struct MinHeapNode* root = buildHuffmanTree(data, freq, size);int arr[MAX_TREE_HT], top = 0;printCodes(root, arr, top);}int main() {char data[] = {'a', 'b', 'c', 'd', 'e', 'f'};int freq[] = {5, 9, 12, 13, 16, 45};int size = sizeof(data) / sizeof(data[0]);HuffmanCodes(data, freq, size);return 0;}```在这个示例代码中,我们首先定义了一个`MinHeapNode`结构体,用于表示哈夫曼树中的节点。
哈夫曼树源代码
#include<iostream>#include<string>#include<fstream>using namespace std;#define Max 200 //最大结点数目#define INT 10000char ch[Max]; //叶子结点信息〔字符〕int i,w[Max]; //w为输入的权值数组typedef struct{unsigned int weight; //权值unsigned int parent,lchild,rchild;}HTNode,*HuffmanTree; //动态分配数组存储赫夫曼树typedef char * *HuffmanCode; //动态分配数组存储赫夫曼编码表void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){//w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC。
int s1,s2,j,min1,min2;if(n<=1) return;int m=2*n-1;HT=new HTNode[m+1];//0号单元未用for(i=1;i<=n;++i) //赫夫曼树叶子结点的初始化{HT[i].weight=w[i]; HT[i].parent=0;HT[i].lchild=0; HT[i].rchild=0;}for(i=n+1;i<=m;++i) //非叶子结点的初始化{HT[i].weight=0; HT[i].parent=0;HT[i].lchild=0; HT[i].rchild=0;}for(i=n+1;i<=m;++i) //建赫夫曼树{ //在HT[1..i-1]选择parent为0且weight最小的两个结点,其序号分别为S1和S2 min1=min2=INT;for(j=1;j<i;j++)if(HT[j].parent==0&&(HT[j].weight<min1)){ min1=HT[j].weight; s1=j; }for(j=1;j<i;j++)if(HT[j].parent==0&&(HT[j].weight<min2)&&j!=s1){ min2=HT[j].weight; s2=j; }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;ch[i]='?';//非叶子结点的结点字符}//从叶子到根逆向求每个字符的赫夫曼编码HC=new char*[n+1]; //分配n个字符编码的头指针向量char *cd=new char[n]; //分配求编码的工作空间HT[i].lchild=s1; HT[i].rchild=s2;cd[n-1]='\0'; //编码结束符for(i=1;i<=n;i++) //逐个字符求赫夫曼编码{int c,f,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';elsecd[--start]='1';HC[i]=new char[n-start];//为第i个字符编码分配空间strcpy(HC[i],&cd[start]); //从cd复制编码〔串〕到HC}delete cd;}void Initialization(HuffmanTree &HT,HuffmanCode &HC,int &n)//初始化,注意加引用符号{char c;ifstream fin("hfmTree.txt",ios::in);//读出if(fin.fail()) //假设不存在此文件,那么从终端读入{cout<<"请输入字符个数n:";cin>>n;cout<<"请输入字符及相应权值:"<<endl;for(i=1;i<=n;i++)//注意点{//getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和tab)。
哈夫曼树的构造代码
哈夫曼树的构造代码x#include<stdio.h>#include<malloc.h>//定义哈夫曼树节点typedef struct{tint weight;//权值tint lchild,rchild,parent;//子节点和双亲节点序号}HTNode;//定义哈夫曼树typedef struct{tHTNode *nodes;//节点数组tint length;//树的节点数}HuffmanTree;//创建哈夫曼树HuffmanTree *createHuffmanTree(int *set,int length){tint m,i,j,x1,x2;//m表示总节点数,x1和x2记录权值最小的两个节点tHuffmanTree *tree;tHTNode *node;tm=2*length-1;t//申请树的节点数组ttree=(HuffmanTree*)malloc(sizeof(HuffmanTree));tnode=(HTNode*)malloc(m*sizeof(HTNode));t//初始化tfor(i=0;i<m;i++)t{ttnode[i].parent=-1;ttnode[i].lchild=-1;ttnode[i].rchild=-1;ttif(i<length)tt{tttnode[i].weight=set[i];tt}ttelsetttnode[i].weight=0;t}t//建立哈夫曼树tfor(i=length;i<m;i++)t{tt//x1表示权值最小的节点序号,x2表示次最小节点的序号ttx1=0;ttx2=0;tt//找出权值最小的节点ttfor(j=0;j<i;j++)tt{tttif(node[j].parent==-1)ttt{ttttif((x1==0)||node[j].weight<node[x1].weight)tttt{tttttx1=j;tttt}ttt}tt}tt//找出权值次最小的节点ttfor(j=0;j<i;j++)tt{tttif(node[j].parent==-1)ttt{ttttif((x2==0)||node[j].weight<node[x2].weight&&x1!=j) tttt{tttttx2=j;tttt}ttt}tt}tt//建立一个新的节点ttnode[i].weight=node[x1].weight+node[x2].weight; ttnode[i].lchild=x1;ttnode[i].rchild=x2;ttnode[x1].parent=i;ttnode[x2].parent=i;t}ttree->nodes=node;ttree->length=m;treturn tree;}//打印哈夫曼树void printHuffmanTree(HuffmanTree *tree){tint i;tprintf('序号t权值t双亲t左孩子t右孩子');tfor(i=0;i<tree->length;i++)t{ttprintf('%dt%dt%dt%dt%d',i,tree->nodes[i].weight,tree->nodes[i].parent, ttttree->nodes[i].lchild,tree->nodes[i].rchild); t}}//释放哈夫曼树void clearHuffmanTree(HuffmanTree *tree){tif(tree==NULL)ttreturn;tfree(tree->nodes);tfree(tree);}int main(){tHuffmanTree *tree;tint set[7]={5,29,7,8,14,23,3};t//创建哈夫曼树ttree=createHuffmanTree(set,7);t//打印哈夫曼树tprintHuffmanTree(tree);t//释放哈夫曼树tclearHuffmanTree(tree);treturn 0; }。
哈夫曼树的创建-c语言源码【采用int型存储】(可打印修改)
精品内容
for(i=0;i<n;i++) {
printf("%c.",'a'+i); for(j=Huffcode[i].start+1;j<n;j++) {
printf("%d",Huffcode[i].bit[j]); } printf("\n"); }
}
int main() {
int * temp; FILE *fp; int length,i=0,j; int w[50]; double W[50]; int a[50]; char str[1000];
m1=m2=100; x1=x2=0;
for(j=0;j<n+i;j++) {
if(HN[j].weight<m1&&HN[j].parent==-1) {
m2=m1; x2=x1; m1=HN[j].weight;
精品内容
x1=j; } else if(HN[j].weight<m2&&HN[j].parent==-1) {
printf("%c.",'a'+i); for(j=Huffcode[i].start+1;j<nod;j++) {
精品内容
printf("%d",Huffcode[i].bit[j]); } printf("\n"); i++; }
if(Q[f].lchild!=-1) {
r++; Q[r]=HT[Q[f].lchild]; } if(Q[f].rchild!=-1) { r++; Q[r]=HT[Q[f].rchild]; } } }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>#include<windows.h> typedef struct{float weight;int flag;int parent;int lchild;int rchild;}huffnode,*HuffmanTree; typedef struct{int bits[30];int start;}huffcode;void numbers(int q){int num=10000;int i,j,x1,x2,n,c,p;float m1,m2;char ch,sh;FILE *fp;char filename[30];printf("请给新文件命名:");scanf("%s",filename);fp=fopen(filename,"w+");n=10;float sum[10]={0};for(i=1; i<=num; i++){ch=rand()%10;sum[ch]++;printf("%c",ch+'0');fprintf(fp,"%c",ch+'0');//fclose(fp);}fflush(stdin);printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");printf("\t\t* 接下来为你计算各个数字权值(请稍等)! *\n");printf("\t\t********************************* ************");Sleep(4*1000);fflush(stdin);//scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");scanf("%c",&sh);system("cls");printf("\t\t各数字权值如下:\n");for(i=0;i<n;i++){printf("\t\t%d\t%f\n",i,sum[i]/10000);}scanf("%c",&sh);huffnode huff_node[19];huffcode huff_code[10],cd;for(i=0;i<2*n-1;i++){huff_node[i].weight=0;huff_node[i].parent=0;huff_node[i].flag=0;huff_node[i].lchild=0;huff_node[i].rchild=0;}for(i=0;i<n;i++){huff_node[i].weight=sum[i];}for(i=0;i<n-1;i++){m1=m2=20000;x1=x2=0;for(j=0;j<n+i;j++){if(huff_node[j].weight<m1&&huff_node[j].flag==0){m2=m1;x2=x1;m1=huff_node[j].weight;x1=j;}else if(huff_node[j].weight<m2&&huff_node[j].flag==0){m2=huff_node[j].weight;x2=j;}}huff_node[x1].parent=n+i;huff_node[x2].parent=n+i;huff_node[x1].flag=1;huff_node[x2].flag=1;huff_node[n+i].weight=huff_node[x1].weight+huff _node[x2].weight;huff_node[n+i].lchild=x1;huff_node[n+i].rchild=x2;}for(i=0;i<n;i++){cd.start=n-1;c=i;p=huff_node[c].parent;while(p!=0){if(huff_node[p].lchild==c)cd.bits[cd.start]=0;elsecd.bits[cd.start]=1;cd.start--;c=p;p=huff_node[p].parent;}cd.start++;for(j=cd.start;j<n;j++)huff_code[i].bits[j]=cd.bits[j];huff_code[i].start=cd.start;}puts("各数字的哈夫曼编码是:");for(i=0;i<n;i++){printf("%d ",i);for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}HuffmanTree t;char str[500];fflush(stdin);scanf("%c",&sh);system("cls");//fflush(stdin);//scanf("%c",&sh);puts("\t\t***************************"); puts("\t\t* 下面开始哈夫曼解码*");puts("\t\t***************************"); for(i=0;i<n;i++){printf("\t%d ",i);for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}while(1){state2:printf("请输入待解码:");scanf("%s",str);int L=strlen(str);for(j=0;j<L;j++){if(str[j]!='0'&&str[j]!='1'&&str[j]!='\0'){puts("待解码中有错误码,请重新输入!");goto state2;}}j=0;while(j<L){t=&huff_node[2*n-2];while(t->lchild||t->rchild){if(str[j]=='0'){i=t->lchild;t=&huff_node[i];}else if(str[j]=='1'){i=t->rchild;t=&huff_node[i];}elsegoto state1;j++;}printf("%d",i);}state1:printf("\n");}}void Capital_letters(int q){int num=10000;int i,j,x1,x2,n,c,p;float m1,m2;char ch,sh;FILE *fp;char filename[30];printf("请给新文件命名:");scanf("%s",filename);fp=fopen(filename,"w+");n=26;float sum[26]={0};for(i=1; i<=num; i++){ch=rand()%26+'A';sum[ch-'A']++;printf("%c",ch);fprintf(fp,"%c",ch);//fclose(fp);}fflush(stdin);printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");printf("\t\t* 接下来为你计算各个字符权值(请稍等)! *\n");printf("\t\t********************************* ************");Sleep(4*1000);fflush(stdin);//scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");scanf("%c",&sh);system("cls");printf("\t\t各数权值如下:\n");for(i=0;i<n;i++){printf("\t\t%c\t%f\n",i+'A',sum[i]/10000);}scanf("%c",&sh);huffnode huff_node[51];huffcode huff_code[26],cd;for(i=0;i<2*n-1;i++){huff_node[i].weight=0;huff_node[i].parent=0;huff_node[i].flag=0;huff_node[i].lchild=0;huff_node[i].rchild=0;}for(i=0;i<n;i++){huff_node[i].weight=sum[i];}for(i=0;i<n-1;i++){m1=m2=20000;x1=x2=0;for(j=0;j<n+i;j++){if(huff_node[j].weight<m1&&huff_node[j].flag==0){m2=m1;x2=x1;m1=huff_node[j].weight;x1=j;}else if(huff_node[j].weight<m2&&huff_node[j].flag==0){m2=huff_node[j].weight;x2=j;}}huff_node[x1].parent=n+i;huff_node[x2].parent=n+i;huff_node[x1].flag=1;huff_node[x2].flag=1;huff_node[n+i].weight=huff_node[x1].weight+huff _node[x2].weight;huff_node[n+i].lchild=x1;huff_node[n+i].rchild=x2;}for(i=0;i<n;i++){cd.start=n-1;c=i;p=huff_node[c].parent;while(p!=0){if(huff_node[p].lchild==c)cd.bits[cd.start]=0;elsecd.bits[cd.start]=1;cd.start--;c=p;p=huff_node[p].parent;}cd.start++;for(j=cd.start;j<n;j++)huff_code[i].bits[j]=cd.bits[j];huff_code[i].start=cd.start;}puts("各字符的哈夫曼编码是:");for(i=0;i<n;i++){printf("%c ",i+'A');for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}HuffmanTree t;char str[500];fflush(stdin);scanf("%c",&sh);system("cls");//fflush(stdin);//scanf("%c",&sh);puts("\t\t***************************"); puts("\t\t* 下面开始哈夫曼解码*");puts("\t\t***************************"); for(i=0;i<n;i++){printf("\t%c ",i+'A');for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}while(1){state2:printf("请输入待解码:");scanf("%s",str);int L=strlen(str);for(j=0;j<L;j++){if(str[j]!='0'&&str[j]!='1'&&str[j]!='\0'){puts("待解码中有错误码,请重新输入!");goto state2;}}j=0;while(j<L){t=&huff_node[2*n-2];while(t->lchild||t->rchild){if(str[j]=='0'){i=t->lchild;t=&huff_node[i];}else if(str[j]=='1'){i=t->rchild;t=&huff_node[i];}elsegoto state1;j++;}printf("%c",i+'A');}state1:printf("\n");}}void Lower_letters(int q){int num=10000;int i,j,x1,x2,n,c,p;float m1,m2;char ch,sh;FILE *fp;char filename[30];printf("请给新文件命名:");scanf("%s",filename);fp=fopen(filename,"w+");n=26;float sum[26]={0};for(i=1; i<=num; i++){ch=rand()%26+'a';sum[ch-'a']++;printf("%c",ch);fprintf(fp,"%c",ch);//fclose(fp);}fflush(stdin);printf("\n\n\n\n\t\t以上就是产生的所有随机数!\n\n"); printf("\t\t按回车键继续!");scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t***************** ****************************\n");printf("\t\t* 接下来为你计算各个数字权值(请稍等)! *\n");printf("\t\t********************************* ************");Sleep(4*1000);fflush(stdin);//scanf("%c",&sh);system("cls");printf("\n\n\n\n\n\n\n\n\n\t\t计算完毕!");scanf("%c",&sh);system("cls");printf("\t\t各数权值如下:\n");for(i=0;i<n;i++){printf("\t\t%c\t%f\n",i+'a',sum[i]/10000);}scanf("%c",&sh);huffnode huff_node[51];huffcode huff_code[26],cd;for(i=0;i<2*n-1;i++){huff_node[i].weight=0;huff_node[i].parent=0;huff_node[i].flag=0;huff_node[i].lchild=0;huff_node[i].rchild=0;}for(i=0;i<n;i++){huff_node[i].weight=sum[i];}for(i=0;i<n-1;i++){m1=m2=20000;x1=x2=0;for(j=0;j<n+i;j++){if(huff_node[j].weight<m1&&huff_node[j].flag==0){m2=m1;x2=x1;m1=huff_node[j].weight;x1=j;}else if(huff_node[j].weight<m2&&huff_node[j].flag==0){m2=huff_node[j].weight;x2=j;}}huff_node[x1].parent=n+i;huff_node[x2].parent=n+i;huff_node[x1].flag=1;huff_node[x2].flag=1;huff_node[n+i].weight=huff_node[x1].weight+huff _node[x2].weight;huff_node[n+i].lchild=x1;huff_node[n+i].rchild=x2;}for(i=0;i<n;i++){cd.start=n-1;c=i;p=huff_node[c].parent;while(p!=0){if(huff_node[p].lchild==c)cd.bits[cd.start]=0;elsecd.bits[cd.start]=1;cd.start--;c=p;p=huff_node[p].parent;}cd.start++;for(j=cd.start;j<n;j++)huff_code[i].bits[j]=cd.bits[j];huff_code[i].start=cd.start;}puts("各字符的哈夫曼编码是:");for(i=0;i<n;i++){printf("%c ",i+'a');for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}HuffmanTree t;char str[500];fflush(stdin);scanf("%c",&sh);system("cls");//fflush(stdin);//scanf("%c",&sh);puts("\t\t***************************"); puts("\t\t* 下面开始哈夫曼解码*");puts("\t\t***************************"); for(i=0;i<n;i++){printf("\t%c ",i+'a');for(j=huff_code[i].start;j<n;j++)printf("%10d",huff_code[i].bits[j]);printf("\n");}while(1){state2:printf("请输入待解码:");scanf("%s",str);int L=strlen(str);for(j=0;j<L;j++){if(str[j]!='0'&&str[j]!='1'&&str[j]!='\0'){puts("待解码中有错误码,请重新输入!");goto state2;}}j=0;while(j<L){t=&huff_node[2*n-2];while(t->lchild||t->rchild){if(str[j]=='0'){i=t->lchild;t=&huff_node[i];}else if(str[j]=='1'){i=t->rchild;t=&huff_node[i];}elsegoto state1;j++;}printf("%c",i+'a');}state1:printf("\n");}}void menu(){system("cls");printf("\t========================== ============\n");printf("\t||||\n");printf("\t|| 随机字符有三种类型:||\n");printf("\t|| 0:数字||\n");printf("\t|| 1:小写字母||\n");printf("\t|| 2:大写字母||\n");printf("\t||||\n");printf("\t========================== ============\n");printf("\t 请选择你需要的字符类型(0-2):"); }void main(){while(1){int choose;menu();scanf("%d",&choose);switch(choose){case 0:numbers(choose);break;case 1:Capital_letters(choose);break;case 2:Lower_letters(choose);break;default:printf("\n\t\t输入有误!!请重新输入!!!");fflush(stdin);Sleep(3*1000);system("cls");menu();}}}。