如何进行哈夫曼编码的

已知在一段报文中有a、b、c、d、e、f六个字符,每个字符出现
的频率依次为a:45,b:13,c:12,d:16,e:9,f:5。要求对每个
字符进行编码要求所发出的报文总长度最短,并求该报文的平均码长。
(一)针对案例中的问题,寻找解决方法并进行理论解决。
1.利用哈夫曼编码对六个字符根据权重建立哈夫曼树。
3.对哈夫曼树进行编码。
4.根据哈夫曼树得出每个字符的哈夫曼编码。

(二)针对案例中的问题,将理论过程转化为代码程序,利用计算机解决
该类问题。
1.在第一步的基础上,运用C语言,将第一步哈夫曼编码的过程转化
为代码程序解决。
2.输入需要编码的字符个数及每个字符的权重,利用程序得出每个字符的哈夫
曼编码。 

给定权值,哈弗曼编码、译码_给定字符和权值,设计每个字符的赫夫曼编码_快乐键盘侠的博客-CSDN博客 题目描述假设某通信报文的字符集由A,B,C,D,E,F这6个字符组成,它们在报文中出现的频度(频度均为整数值)。(1)构造一棵哈弗曼树,依次给出各字符编码结果。(2)给字符串进行编码。(3)给编码串进行译码。规定:构建哈弗曼树时:左子树根结点权值小于等于右子树根结点权值。生成编码时:左分支标0,右分支标1。输入第一行:依次输入6个整数,依次代表A,B,C,D,E,F的频度,用空格隔开。第二行:待编码的字符串第三行:待译码的编码串输出前6行依次输出各个字符及其对应编码,格式为【字符: https://blog.csdn.net/qq_42843894/article/details/115454824

参考

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7423862
  • 除此之外, 这篇博客: 纸牌游戏(C语言实现)中的 星期天小哼和小哈约在一起玩桌游,他们正在玩一个非常古怪的扑克游戏——“小猫钓鱼”。游戏的规则是这样的:将一副扑克牌平均分成两份,每人拿一份。小哼先拿出手中的第一张扑克牌放在桌上,然后小哈也拿出手中的第一张扑克牌,并放在小哼刚打出的扑克牌的上面,就像这样两人交替出牌。出牌时,如果某人打出的牌与桌上某张牌的牌面相同,即可将两张相同的牌及其中间所夹的牌全部取走,并依次放到自己手中牌的末尾。当任意一人 手中的牌全部出完时,游戏结束,对手获胜。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • **

    #include <stdio.h>
    #include <stdlib.h>
    struct queue{
    	int head;
    	int tail;
    	int data[1000];
    };
    struct stack{
    	int top;
    	int data[10];
    };
    int main()
    {
    	int i,t;
    	struct queue q1,q2;
    	struct stack s;
    	int book[10];
    	
    	q1.head=1;q1.tail=1;
    	q2.head=1;q2.tail=1;
    	
    	s.top=0;
    	for(i=1;i<=9;i++)
    		book[i]=0;
    		
    	for(i=1;i<=6;i++){
    		scanf("%d",&q1.data[q1.tail]);
    		q1.tail++;
    	}
    	for(i=1;i<=6;i++){
    		scanf("%d",&q2.data[q2.tail]);
    		q2.tail++;
    	}
    	while(q1.head<q1.tail&&q2.head<q2.tail)
    	{
    		t=q1.data[q1.head];
    		if(book[t]==0){
    		q1.head++;//q1出牌,即出队列,头指针+1
    		s.top++;//桌面上的牌为栈,仅有头指针操作 
    		s.data[s.top]=t;
    		book[t]=1;
    		}
    		else{
    		q1.head++;
    		q1.data[q1.tail]=t;
    		q1.tail++;
    		while(s.data[s.top]!=t)
    		{
    			book[s.data[s.top]]=0;
    			q1.data[q1.tail]=s.data[s.top];
    			q1.tail++;
    			s.top--;
    		}
    		}
    		t=q2.data[q2.head];
    		if(book[t]==0)
    		{
    			q2.head++;
    			s.top++;
    			s.data[s.top]=t;
    			book[t]=1;
    		}
    		else
    		{
    			q2.head++;
    			q2.data[q2.tail]=t;
    			q2.tail++;
    			while(s.data[s.top]!=t)
    			{
    				q2.data[q2.tail]=s.data[s.top];
    				book[s.data[s.top]]=0;
    				q2.tail++;
    				s.top--;
    			}
    		}
    	}
    	if(q2.head==q2.tail)
    	{
    		printf("q1 win\n");
    		for(i=q1.head;i<q1.tail;i++)//tail始终指向结尾的下一个位置
    			printf("%d ",q1.data[i]);
    	}
    	else
    	{
    		printf("q2 win\n");
    		for(i=q2.head;i<q2.tail;i++)
    			printf("%d ",q2.data[i]);
    	}
    	return 0;
    }
    
  • 以下回答由chatgpt基于相关博客总结生成:

    理论解决方案

    1. 根据字符出现的频率建立哈夫曼树。首先将这些字符作为叶子节点,在每个节点上标记该字符的频率,将所有节点按其频率值从小到大排序,选取频率最小的两个节点建立一个新的节点,其频率值为这两个节点的频率之和,并将这个新的节点插入原先的序列中。重复这个过程,直到序列中只包含一个节点为止,此节点即为根节点,哈夫曼树建立完成。

    2. 对哈夫曼树进行编码。从根节点开始,往左走为 0,往右走为 1。对于每个字符,将其在树中走到的路径上的数字记录下来,例如从根节点到字符 a 所在的节点路径为左-右-左,则该字符的编码为 010。

    3. 根据哈夫曼树得出每个字符的哈夫曼编码。将每个字符在哈夫曼树上的路径记录在代码中,可以使用字符串或数组表示编码,例如字符 a 的编码为 "010" 或 {0,1,0}。

    4. 对于给定的报文,根据每个字符的频率和哈夫曼编码进行编码。将每个字符替换为其对应的哈夫曼编码,并将所有替换后的编码拼接在一起即可得到报文的完整编码。

    5. 计算平均码长。平均码长的计算公式为:∑(每个字符的频率 × 对应的编码长度)。将每个字符的频率和对应的编码长度代入公式中进行计算即可得出平均码长。

    C语言实现

    #include <stdio.h>
    #include <string.h>
    
    #define MAX_CHAR_NUM 6
    
    struct Node {
        char c;
        int freq;
        char code[MAX_CHAR_NUM];
        struct Node* left;
        struct Node* right;
    };
    
    void sort_node_list(struct Node** node_list, int len) {
        // 冒泡排序
        for (int i = 0; i < len - 1; ++i) {
            for (int j = 0; j < len - i - 1; ++j) {
                if (node_list[j]->freq > node_list[j + 1]->freq) {
                    struct Node* tmp = node_list[j];
                    node_list[j] = node_list[j + 1];
                    node_list[j + 1] = tmp;
                }
            }
        }
    }
    
    struct Node* create_node_list() {
        struct Node* node_list[MAX_CHAR_NUM];
        int freq[] = {45, 13, 12, 16, 9, 5};
        for (int i = 0; i < MAX_CHAR_NUM; ++i) {
            char c = 'a' + i;
            struct Node* node = (struct Node*)malloc(sizeof(struct Node));
            node->c = c;
            node->freq = freq[i];
            node->left = node->right = NULL;
            node_list[i] = node;
        }
        return node_list[0];
    }
    
    struct Node* create_huffman_tree() {
        struct Node* node_list = create_node_list();
        int len = MAX_CHAR_NUM;
        while (len > 1) {
            struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
            new_node->freq = node_list[0]->freq + node_list[1]->freq;
            new_node->left = node_list[0];
            new_node->right = node_list[1];
            for (int i = 2; i < len; ++i) {
                node_list[i - 2] = node_list[i];
            }
            node_list[len - 2] = new_node;
            --len;
            sort_node_list(node_list, len);
        }
        return node_list[0];
    }
    
    void assign_codes(struct Node* node, char* code, int depth) {
        if (!node->left && !node->right) {
            strncpy(node->code, code, MAX_CHAR_NUM);
            return;
        }
        code[depth] = '0';
        assign_codes(node->left, code, depth + 1);
        code[depth] = '1';
        assign_codes(node->right, code, depth + 1);
        code[depth] = '\0';
    }
    
    void print_codes(struct Node* root, FILE* fp) {
        if (root->left) {
            fprintf(fp, "%c ", root->c);
            fprintf(fp, "%s\n", root->code);
            print_codes(root->left, fp);
            print_codes(root->right, fp);
        }
    }
    
    void encode(char* text, int len, FILE* fp) {
        char code[MAX_CHAR_NUM];
        char code_buffer[MAX_CHAR_NUM * len];
        memset(code_buffer, 0, MAX_CHAR_NUM * len);
        for (int i = 0; i < len; ++i) {
            char c = text[i];
            struct Node* node = huffman_tree;
            while (node && node->c != c) {
                if (text[i] < node->c) {
                    node = node->left;
                } else {
                    node = node->right;
                }
            }
            strncat(code_buffer, node->code, MAX_CHAR_NUM);
        }
        fprintf(fp, "%s\n", code_buffer);
    }
    
    int main() {
        struct Node* huffman_tree = create_huffman_tree();
        char code[MAX_CHAR_NUM] = {0};
        assign_codes(huffman_tree, code, 0);
        FILE* fp = fopen("huffman_codes.txt", "w");
        print_codes(huffman_tree, fp);
        fclose(fp);
        char text[] = "aabcbd";
        encode(text, strlen(text), fp);
        return 0;
    }