再写 Huffman_Tree

本文详细介绍了如何使用Huffman树进行数据压缩编码的过程,并通过实例展示了Huffman树的构造、观察和编码应用,包括算法实现、数据结构设计及编码结果展示。

之前写的huffman树的代码

这次的只是对建树过程的代码做了一点改变,对比代码一看就知道了

tree.h

#include<iostream>
using namespace std;

//栈模版
template<class T>
class My_stack;

template<class T>
class Node		//结点类
{
private:
	T data;
	Node<T> *next;
public:
	Node()
	{
		next=NULL;
	}
	Node(T d)
	{
		data=d;
		next=NULL;
	}
	friend My_stack<T>;
};

template<class T>
class My_stack
{
private:
	Node<T> *head;
public:
	My_stack()
	{
		head=new Node<T>();
	}
	
	~My_stack()
	{
		clean();
		delete head;
	}
	
	bool empty() const
	{
		return (head->next==0);
	}
	
	void push(T d)	//入栈
	{
		Node<T> *p=new Node<T>(d);
		p->next=head->next;
		head->next=p;
	}
	
	T top()	//返回栈顶元素
	{
		if(empty())
		{
			cout<<"stack is empty."<<endl;
			exit(1);
		}
		Node<T> *p=head->next;
		T temp=p->data;
		return temp;
	}
	
	void pop()	//弹出栈顶元素
	{
		Node<T> *p=head->next;
		head->next=p->next;
		delete p;
	}
	
	void clean()	//清除整个栈
	{
		Node<T> *p=head->next;
		while(p)
		{
			head->next=p->next;
			delete p;
			head->next=p;
		}
	}
};

//放叶子结点信息的结构体
struct node
{
	char name;
	int data;
};

class HuffmanTree;

class HuffmanNode
{
	char name;
	int data;
	int parent,lchild,rchild;
	friend HuffmanTree;
};

class HuffmanTree
{
public:
	void Create_HuffmanTree(HuffmanNode *&HT,node w[],int n)
	{
		//用w申请的数组暂时保存权值(暂时设定全都大于0)
		if(n<1)
		{
			cout<<"参数不合理"<<endl;
			return ;
		}
		
		int m=2*n-1; //n个叶子结点的哈夫曼树总共有2*n-1个结点
		
		HT=new HuffmanNode[m]; //分配m个huffman结点
		
		int i,k,lnode,rnode;
		double min1,min2; //存放两个最小的结点值
		for(i=0;i<n;i++)
		{
			HT[i].name=w[i].name;
			HT[i].data=w[i].data;
			HT[i].lchild=-1;
			HT[i].rchild=-1;
			HT[i].parent=-1;
		}
		for(int j=i;j<m;j++)
		{
			HT[j].name='#';
			HT[j].data=0;
			HT[j].lchild=-1;
			HT[j].rchild=-1;
			HT[j].parent=-1;
		}
		//结点初始化完成,下面开始构造huffman树	
		for(i=n;i<2*n-1;i++)
		{		
			min1=min2=32767;
			lnode=rnode=-1;
			for(k=0;k<=i-1;k++)
			{
				if(-1 == HT[k].parent)
				{
					if(HT[k].data<min1)
					{
						min2=min1;
						rnode=lnode;
						min1=HT[k].data;
						lnode=k;
					}
					else if(HT[k].data<min2)
					{
						min2=HT[k].data;
						rnode=k;
					}
				}
			}
			HT[i].data=min1+min2;
			HT[i].lchild=lnode;
			HT[i].rchild=rnode;
			HT[lnode].parent=i;
			HT[rnode].parent=i;
		}
		cout<<"____huffman树构造完成____"<<endl;
	}

	void Traverse(HuffmanNode *HT,int n) //观察
	{
		int m=2*n-1;
		for(int i=m-1;i>=n;i--)
		{
			cout<<HT[i].data<<"={";
			cout<<HT[HT[i].lchild].data<<',';
			cout<<HT[HT[i].rchild].data<<'}';
			cout<<endl;
		}
	}

	void Huffman_Coding(HuffmanNode *HT,int n)
	{
		HuffmanNode *q;
		int f,temp,p;
		My_stack<int> s;
		for(int i=0;i<n;i++)
		{	
			q=HT;
			f=i;
			p=q[f].parent;
			while(p!=-1)
			{
				if(q[p].lchild==f)
					temp=0;
				else
					temp=1;
				s.push(temp);
				f=p;
				p=q[p].parent;
			}
			cout<<"第"<<i+1<<"个字符 "<<HT[i].name<<" 的huffman编码为:";
			while(!s.empty())
			{
				cout<<s.top()<<" ";
				s.pop();
			}
			cout<<endl;
		}
	}
};

main.cpp

#include"tree.h"

int main()
{
	int n;
	node *p;
	cout<<"输入要编码的字母数目:";
	cin>>n;
	p=new node[n];
	cout<<"输入各个字母的名字和频率权值大小:";
	for(int i=0;i<n;i++)
		cin>>p[i].name>>p[i].data;
	
	cout<<"____构造huffman树____"<<endl;
	HuffmanTree tree;
	HuffmanNode *HT;
	tree.Create_HuffmanTree(HT,p,n);
	
	cout<<"huffman树的结构为:"<<endl;
	tree.Traverse(HT,n);
	cout<<endl;

	cout<<"____Huffman_Coding_____"<<endl;
	tree.Huffman_Coding(HT,n);
	
	return 0;
}

测试数据:

输入要编码的字母数目:8
输入各个字母的名字和频率权值大小:
a 7
b 19
c 2
d 6
e 32
f 3
g 21
h 10
____构造huffman树____
____huffman树构造完成____
huffman树的结构为:
100={40,60}
60={28,32}
40={19,21}
28={11,17}
17={7,10}
11={5,6}
5={2,3}

____Huffman_Coding_____
第1个字符 a 的huffman编码为:1 0 1 0
第2个字符 b 的huffman编码为:0 0
第3个字符 c 的huffman编码为:1 0 0 0 0
第4个字符 d 的huffman编码为:1 0 0 1
第5个字符 e 的huffman编码为:1 1
第6个字符 f 的huffman编码为:1 0 0 0 1
第7个字符 g 的huffman编码为:0 1
第8个字符 h 的huffman编码为:1 0 1 1
Press any key to continue

import heapq from collections import defaultdict import os #哈夫曼树节点定义 class HuffmanNode: def __init__(self, char=None, freq=0, left=None, right=None): self.char = char # 字符 self.freq = freq # 频率 self.left = left # 左子树 self.right = right # 右子树 # 定义优先队列中比较规则(频率小的优先) def __lt__(self, other): return self.freq < other.freq #统计字符频率 def build_frequency(text): freq_map = defaultdict(int) for ch in text: freq_map[ch] += 1 return dict(freq_map) #构建哈夫曼树 def build_huffman_tree(freq_map): heap = [HuffmanNode(char, freq) for char, freq in freq_map.items()] heapq.heapify(heap) #将列表转换为最小堆 while len(heap) > 1: left = heapq.heappop(heap) right = heapq.heappop(heap) merged = HuffmanNode(freq=left.freq + right.freq, left=left, right=right) heapq.heappush(heap, merged) return heap[0] # 根节点 #生成哈夫曼编码表 def generate_codes(root): if root is None: return {} codes = {} def dfs(node, path): if node.char is not None: # 叶子节点 codes[node.char] = path if path else "0" else: dfs(node.left, path + "0") dfs(node.right, path + "1") dfs(root, "") return codes #生成编码表文件 def write_code_table(freq_map, codes, output_path="file1_编码表.txt"): # 按频率从高到低排序 sorted_items = sorted(freq_map.items(), key=lambda x: (-x[1], x[0])) total_bits = sum(freq_map[ch] * len(codes[ch]) for ch in freq_map) with open(output_path, 'w', encoding='utf-8') as f: f.write(f"{'字符':<4} {'频率':<6} {'编码'}\n") for char, freq in sorted_items: code = codes[char] f.write(f"{char:<4} {freq:<6} {code}\n") f.write(f"\n编码总码长:{total_bits}位\n") print(f"字符编码表已保存至 '{output_path}'") # ==================== 步骤5:对原文进行编码并写入二进制文件(文件2)==================== def text_to_binary_stream(text, codes, output_path="file2_编码文件.bin"): # 构建完整比特串 bit_string = ''.join(codes[ch] for ch in text) # 将比特字符串转为字节流 byte_array = bytearray() for i in range(0, len(bit_string), 8): chunk = bit_string[i:i+8] if len(chunk) < 8: chunk = chunk.ljust(8, '0') # 不足补零 byte_array.append(int(chunk, 2)) with open(output_path, 'wb') as f: f.write(byte_array) print(f"哈夫曼编码后的二进制数据已保存至 '{output_path}'") return bit_string # 返回用于调试或计算 # ==================== 步骤6:解码二进制文件(文件3)==================== def decode_binary_file(huffman_root, original_bit_length, output_path="file3_解码文件.txt"): # 重新读取二进制文件并还原比特流 with open("file2_编码文件.bin", 'rb') as f: binary_data = f.read() bit_string = ''.join(f'{byte:08b}' for byte in binary_data) bit_string = bit_string[:original_bit_length] # 截断多余补位 # 解码 decoded_text = "" node = huffman_root for bit in bit_string: node = node.left if bit == '0' else node.right if node.char is not None: decoded_text += node.char node = huffman_root # 回到根节点 with open(output_path, 'w', encoding='utf-8') as f: f.write(decoded_text) print(f"解码后的文本已保存至 '{output_path}'") return decoded_text # ==================== 主函数 ==================== def main(): # 读取输入文本 input_file = "data.txt" if not os.path.exists(input_file): # 若无文件,则创建示例文本 example_text = "一个苹果、一个芒果、一个百香果共三个水果。" with open(input_file, 'w', encoding='utf-8') as f: f.write(example_text) print(f"📄 输入文件 '{input_file}' 不存在,已创建示例文本:") print(example_text) else: with open(input_file, 'r', encoding='utf-8') as f: example_text = f.read().strip() print("🔤 开始处理文本:", example_text) # 1. 统计频率 freq_map = build_frequency(example_text) # 2. 构建哈夫曼树 huffman_tree = build_huffman_tree(freq_map) # 3. 生成编码表 codes = generate_codes(huffman_tree) # 4. 写编码表(文件1) write_code_table(freq_map, codes) # 5. 编码原文并写入二进制文件(文件2) bit_stream = text_to_binary_stream(example_text, codes) original_bit_length = len(bit_stream) # 6. 解码并写回原文(文件3) decoded = decode_binary_file(huffman_tree, original_bit_length) # 验证正确性 if decoded == example_text: print("压缩与解压成功,文本一致!") else: print("出错:解码后文本与原文字不符!") if __name__ == "__main__": main()大白话详细解释每一行代码的作用
最新发布
12-12
""" 对图像哈夫曼编码/解码,大致步骤是根据哈夫曼编码灰度图像,对图像进行编码,并保存成二级制的文件,保存到指定文件中;读取哈夫曼编码的文件,解码成图像,与原图像对比。 """ import cv2 from queue import PriorityQueue import numpy as np import math import struct #哈夫曼树的节点类 class HuffmanNode(object): def __init__(self, value, key=None, symbol='', left_child=None, right_child=None): ''' 初始化哈夫曼树的节点 :param value: 节点的值,i.e. 元素出现的频率 :param key: 节点代表的元素,非叶子节点为None :param symbol: 节点的哈夫曼编码,初始化必须为空字符串 :param left_child: 左子节点 :param right_child: 右子节点 ''' self.left_child = left_child self.right_child = right_child self.value = value self.key = key assert symbol == '' self.symbol = symbol def __eq__(self, other): ''' 用于比较两个HuffmanNode的大小,等于号,根据value的值比较 :param other: :return: ''' return self.value == other.value def __gt__(self, other): ''' 用于比较两个HuffmanNode的大小,大于号,根据value的值比较 :param other: :return: ''' return self.value > other.value def __lt__(self, other): ''' 用于比较两个HuffmanNode的大小,小于号,根据value的值比较 :param other: :return: ''' return self.value < other.value def createTree(hist_dict: dict) -> HuffmanNode: ''' 构造哈夫曼树 可以写一个HuffmanTree的类 :param hist_dict: 图像的直方图,dict = {pixel_value: count} :return: HuffmanNode, 哈夫曼树的根节点 ''' # 借助优先级队列实现直方图频率的排序,取出和插入元素很方便 q = PriorityQueue() # 根据传入的像素值和频率字典构造哈夫曼节点并放入队列中 for k, v in hist_dict.items(): # 这里放入的都是之后哈夫曼树的叶子节点,key都是各自的元素 q.put(HuffmanNode(value=v, key=k)) # 判断条件,直到队列中只剩下一个根节点 while q.qsize() > 1: # 取出两个最小的哈夫曼节点,队列中这两个节点就不在了 l_freq, r_freq = q.get(), q.get() # 增加他们的父节点,父节点值为这两个哈夫曼节点的和,但是没有key值;左子节点是较小的,右子节点是较大的 node = HuffmanNode(value=l_freq.value + r_freq.value, left_child=l_freq, right_child=r_freq) # 把构造的父节点放在队列中,继续排序和取放、构造其他的节点 q.put(node) # 队列中只剩下根节点了,返回根节点 return q.get() def walkTree_VLR(root_node: HuffmanNode, symbol=''): ''' 前序遍历一个哈夫曼树,同时得到每个元素(叶子节点)的编码,保存到全局的Huffman_encode_dict :param root_node: 哈夫曼树的根节点 :param symbol: 用于对哈夫曼树上的节点进行编码,递归的时候用到,为'0'或'1' :return: None ''' # 为了不增加变量复制的成本,直接使用一个dict类型的全局变量保存每个元素对应的哈夫曼编码 global Huffman_encode_dict # 判断节点是不是HuffmanNode,因为叶子节点的子节点是None if isinstance(root_node, HuffmanNode): # 编码操作,改变每个子树的根节点的哈夫曼编码,根据遍历过程是逐渐增加编码长度到完整的 root_node.symbol += symbol # 判断是否走到了叶子节点,叶子节点的key!=None if root_node.key != None: # 记录叶子节点的编码到全局的dict中 Huffman_encode_dict[root_node.key] = root_node.symbol # 访问左子树,左子树在此根节点基础上赋值'0' walkTree_VLR(root_node.left_child, symbol=root_node.symbol + '0') # 访问右子树,右子树在此根节点基础上赋值'1' walkTree_VLR(root_node.right_child, symbol=root_node.symbol + '1') return def encodeImage(src_img: np.ndarray, encode_dict: dict): ''' 用已知的编码字典对图像进行编码 :param src_img: 原始图像数据,必须是一个向量 :param encode_dict: 编码字典,dict={element:code} :return: 图像编码后的字符串,字符串中只包含'0'和'1' ''' img_encode = "" assert len(src_img.shape) == 1, '`src_img` must be a vector' ########## Begin ########## """ 任务1 用已知的编码字典对图像进行编码,对图像中的每个像素点进行编码,返回值为img_encode,返回的图像编码后的字符串, 字符串中只包含'0'和'1',用for循环进行遍历 """ ########## End ########## return img_encode def writeBinImage(img_encode: str, huffman_file: str): ''' 把编码后的二进制图像数据写入到文件中 :param img_encode: 图像编码字符串,只包含'0'和'1' :param huffman_file: 要写入的图像编码数据文件的路径 :return: ''' # 文件要以二进制打开 with open(huffman_file, 'wb') as f: # 每8个bit组成一个byte for i in range(0, len(img_encode), 8): # 把这一个字节的数据根据二进制翻译为十进制的数字 img_encode_dec = int(img_encode[i:i + 8], 2) # 把这一个字节的十进制数据打包为一个unsigned char,大端(可省略) img_encode_bin = struct.pack('>B', img_encode_dec) # 写入这一个字节数据 f.write(img_encode_bin) def readBinImage(huffman_file: str, img_encode_len: int): ''' 从二进制的编码文件读取数据,得到原来的编码信息,为只包含'0'和'1'的字符串 :param huffman_file: 保存的编码文件 :param img_encode_len: 原始编码的长度,必须要给出,否则最后一个字节对不上 :return: str,只包含'0'和'1'的编码字符串 ''' code_bin_str = "" with open(huffman_file, 'rb') as f: # 从文件读取二进制数据 content = f.read() # 从二进制数据解包到十进制数据,所有数据组成的是tuple code_dec_tuple = struct.unpack('>' + 'B' * len(content), content) for code_dec in code_dec_tuple: # 通过bin把解压的十进制数据翻译为二进制的字符串,并填充为8位,否则会丢失高位的0 # 0 -> bin() -> '0b0' -> [2:] -> '0' -> zfill(8) -> '00000000' code_bin_str += bin(code_dec)[2:].zfill(8) # 由于原始的编码最后可能不足8位,保存到一个字节的时候会在高位自动填充0,读取的时候需要去掉填充的0,否则读取出的编码会比原来的编码长 # 计算读取的编码字符串与原始编码字符串长度的差,差出现在读取的编码字符串的最后一个字节,去掉高位的相应数量的0就可以 len_diff = len(code_bin_str) - img_encode_len # 在读取的编码字符串最后8位去掉高位的多余的0 code_bin_str = code_bin_str[:-8] + code_bin_str[-(8 - len_diff):] return code_bin_str def decodeHuffman(img_encode: str, huffman_tree_root: HuffmanNode): ''' 根据哈夫曼树对编码数据进行解码 :param img_encode: 哈夫曼编码数据,只包含'0'和'1'的字符串 :param huffman_tree_root: 对应的哈夫曼树,根节点 :return: 原始图像数据展开的向量 ''' img_src_val_list = [] # 从根节点开始访问 root_node = huffman_tree_root # 每次访问都要使用一位编码 for code in img_encode: # 如果编码是'0',说明应该走到左子树 if code == '0': root_node = root_node.left_child # 如果编码是'1',说明应该走到右子树 elif code == '1': root_node = root_node.right_child # 只有叶子节点的key才不是None,判断当前走到的节点是不是叶子节点 if root_node.key != None: # 如果是叶子节点,则记录这个节点的key,也就是哪个原始数据的元素 img_src_val_list.append(root_node.key) # 访问到叶子节点之后,下一次应该从整个数的根节点开始访问了 root_node = huffman_tree_root return np.asarray(img_src_val_list) def decodeHuffmanByDict(img_encode: str, encode_dict: dict): ''' 另外一种解码策略是先遍历一遍哈夫曼树得到所有叶子节点编码对应的元素,可以保存在字典中,再对字符串的子串逐个与字典的键进行比对,就得到相应的元素是什么。 用C语言也可以这么做。 这里不再对哈夫曼树重新遍历了,因为之前已经遍历过,所以直接使用之前记录的编码字典就可以。 :param img_encode: 哈夫曼编码数据,只包含'0'和'1'的字符串 :param encode_dict: 编码字典dict={element:code} :return: 原始图像数据展开的向量 ''' img_src_val_list = [] decode_dict = {} ########## Begin ########## """ 任务2 对字典进行遍历,构造一个key-value互换的字典,i.e. dict={code:element},后边方便使用 """ ########## End ########## # s用来记录当前字符串的访问位置,相当于一个指针 s = 0 # 只要没有访问到最后 while len(img_encode) > s + 1: # 遍历字典中每一个键code for k in decode_dict.keys(): # 如果当前的code字符串与编码字符串前k个字符相同,k表示code字符串的长度,那么就可以确定这k个编码对应的元素是什么 if k == img_encode[s:s + len(k)]: img_src_val_list.append(decode_dict[k]) # 指针移动k个单位 s += len(k) # 如果已经找到了相应的编码了,就可以找下一个了 break return np.asarray(img_src_val_list) if __name__ == '__main__': src_img_path = 'project/step2/img_data/ex_1.jpg' # 即使原图像是灰度图,也需要加入GRAYSCALE标志 src_img = cv2.imread(src_img_path, cv2.IMREAD_GRAYSCALE) # 记录原始图像的尺寸,后续还原图像要用到 src_img_w, src_img_h = src_img.shape # 把图像展开成一个行向量 src_img_ravel = src_img.ravel() # {pixel_value:count},保存原始图像每个像素对应出现的次数,也就是直方图 hist_dict = {} # {pixel_value:code},在函数中作为全局变量用到了 Huffman_encode_dict = {} # 得到原始图像的直方图,出现次数为0的元素(像素值)没有加入 for p in src_img_ravel: if p not in hist_dict: hist_dict[p] = 1 else: hist_dict[p] += 1 ########## Begin ########## """ 任务3. 构造哈夫曼树,返回值为huffman_root_node,调用构造哈夫曼树的代码 """ ########## End ########## # 遍历哈夫曼树,并得到每个元素的编码,保存到Huffman_encode_dict walkTree_VLR(huffman_root_node) ########## Begin ########## """ 任务4 根据编码字典编码原始图像得到二进制编码数据字符串,需要调用encodeImage()函数进行将图像二进制编码 """ ########## End ########## # 把二进制编码数据字符串写入到文件中,后缀为bin writeBinImage(img_encode, src_img_path.replace('.jpg', '.bin')) # 读取编码的文件,得到二进制编码数据字符串 img_read_code = readBinImage(src_img_path.replace('.jpg', '.bin'), len(img_encode)) # 解码二进制编码数据字符串,得到原始图像展开的向量 # 这是根据哈夫曼树进行解码的方式 img_src_val_array = decodeHuffman(img_read_code, huffman_root_node) # 确保解码的数据与原始数据大小一致 assert len(img_src_val_array) == src_img_w * src_img_h # 恢复原始二维图像 img_decode = np.reshape(img_src_val_array, [src_img_w, src_img_h]) print(img_decode) print(np.sum(img_decode)) cv2.imwrite('project/step2/stu_img/decode_ex_1.jpg', img_decode)
11-22
任务描述 本关任务要求完成哈夫曼树的相关基本操作,分别实现哈夫曼树的创建、编码等基本操作。 相关知识 哈夫曼树结点Node具有5个存储域data、weight、parent、left和right。 data: 存储结点数据。 weight: 存储权值。 parent: 存储父亲结点地址 left: 存储左儿子结点地址。 right: 存储右儿子结点地址。 哈夫曼码结构体具有2个域data、code。 data: 存储结点数据。 code: 存储哈夫曼编码。 链栈涉及的主要操作如下: 构造函数创建哈夫曼树:创建哈夫曼树。该操作函数具体定义如下: huffmanTree( ) 析构函数释放哈夫曼树存储空间:释放哈夫曼树中所有结点的存储空间。该操作函数具体定义如下: ~huffmanTree( ) 创建哈夫曼树:依据结点数据和权值创建哈夫曼树。该操作函数具体定义如下: void createHuffmanTree(const T *d,const int *w) 输出哈夫曼编码:遍历哈夫曼树打印哈夫曼编码。该操作函数具体定义如下: void printHuffmanCode( ) 挑选权值最小元素:挑选当前权值最小元素用于组建哈夫曼树。该操作函数具体定义如下: void selectMin( int m, int &p ) 编程要求 本关任务是实现step1:哈夫曼树-实现/huffmanTree.h中的createHuffmanTree、printHuffmanCode、selectMin等操作。 请注意,为了能够更好的比对输出结构,在参考教材代码的同时,请删除所有提示信息的输出! 基本操作具体要求如下: * createHuffmanTree:创建哈夫曼树。在创建哈夫曼树时权值较小则做为左儿子 * printHuffmanCode:输出哈夫曼编码。左枝为0右枝为1. * selectMin:挑选权值最小元素。 * 输入输出格式请参见后续测试样例 注意:在实现本关任务的基本操作函数时,可调用以完成的其他操作。 测试说明 本关的测试文件是step1哈夫曼树-实现/main.cpp,负责对实现的代码进行测试。具体代码,可以切换平台代码文件查看。 注意:step1哈夫曼树-实现/main.cpp的代码不能被修改。 以下是平台对step1哈夫曼树-实现/main.cpp的测试样例: 样例输入: 7 //编码字符个数 z h a n g b o //编码字符 8 10 2 5 13 1 4 //编码字符权值 样例输出 z:00 h:01 a:10101 n:100 g:11 b:10100 o:1011 // 和书上代码差别:创建的huffman树左边权值小,右边权值大 #include<iostream> #ifndef _HUFFMAN_TREE_H_ #define _HUFFMAN_TREE_H_ using namespace std; template <class T> class huffmanTree{ private: struct Node{ T data; // 结点数据域 int weight; // 结点的权值 int parent, left, right; // 双亲及左右孩子的下标 Node() { // 构造函数 weight = parent = left = right = 0; }; }; struct huffmanCode { T data; string code; // 保存data的哈夫曼编码 huffmanCode(){ code=""; } // 构造函数 }; Node *hfTree; // 顺序结构,保存huffmanhuffmanCode *hfCode; // 顺序结构,保存结点的huffman编码 int size; // 叶结点数 void selectMin(int m,int& p); // 选出当前集合中的最小元素 public: huffmanTree(int initSize); // 构造函数 ~huffmanTree() {delete [] hfTree;delete []hfCode;} // 析构函数 void createHuffmanTree(const T *d, const int *w);//创建哈夫曼树 void huffmanEncoding(); // 获取huffman编码 void printHuffmanCode(); // 输出huffman编码 }; template <class T> huffmanTree<T>::huffmanTree(int initSize){ size = initSize; // size为初始集合中的结点数 hfTree = new Node[2*size]; hfCode = new huffmanCode[size]; } template <class T> void huffmanTree<T>::createHuffmanTree(const T *d, const int *w) { // 请在这里补充代码,完成本关任务 /********** Begin *********/ /********** End **********/ } template<class T> void huffmanTree<T>::selectMin(int m,int& p){ // 请在这里补充代码,完成本关任务 /********** Begin *********/ … /********** End **********/ } template<class T> void huffmanTree<T>::printHuffmanCode(){ for (int i=0; i< size; i++) cout<< hfCode[i].data <<':' << hfCode[i].code << endl; } #endif
12-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值