`

哈弗曼树与编码解码

阅读更多

大文件M包含许多字符,它们是'a','b','c','d','e','f','g'中的一个,每个富裕唯一编码

1.使用了优先级队列Heap

2.定义接口PriorityQueue

3。改程序限定在祖父记得256个字符之内,每个字符在ArrayList数组中都有一个对应的位置,例如,’B‘,该字符的信息被存储在索引(int)'B'处,即66.详见代码和附件

code:

package Exercize;

public interface PriorityQueue<E> {

	int size() ;
	boolean isEmpty() ;
	void add(E element) ;
	E getMin() ;
	E removeMin() ;
}


package HUffman;

import Exercize.Heap ;
import Exercize.PriorityQueue; 
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;

public class Huffman {

	public final static int SIZE = 256 ;
	
	protected Entry[] leafEntries ;  //以字符ASC||为索引的数组
	protected PriorityQueue<Entry> pq ;
	
	public Huffman(){
	 
		Entry entry ;
		leafEntries = new Entry[SIZE] ;
		for(int i = 0; i < SIZE; i ++)
		{
			leafEntries[i] = new Entry() ;
			entry = leafEntries[i] ;
			entry.freq = 0 ;
			entry.left = null ;
			entry.right = null ;
			entry.parent = null ;
		}
		pq = new Heap<Entry>() ;
		
	}
	
	public void updateFrequencies(String line){
		Entry entry ;
		for(int j = 0; j < line.length(); j ++)
		{
			entry = leafEntries[(int)(line.charAt(j))] ;
			entry.freq ++ ;
		}
		entry = leafEntries[(int)'\r'] ;  //保证消息原来的行结构在解码过程中保持不变
		entry.freq ++ ;
	}
	
	 
	//首先填充leafEntries对象,然后在此基础上填充优先级队列,按照频率递增的顺序插入
	public void createPQ() throws IOException {
		 
		Entry entry ;		 		 
		for(int i = 0 ; i  < SIZE ; i ++){
			 entry = leafEntries[i] ;
			 if(entry.freq > 0)
				 pq.add(entry) ;
		}
	}
		 
	//频率最低的字符优先删除组成树的节点
	public void createHuffmanTree(){
		Entry left, 
			  right, 
			  sum ;
		while(pq.size() > 1){
			left = pq.removeMin() ;
			left.code = "0" ;
			
			right = pq.removeMin() ;
			right.code = "1" ;
			
			sum = new Entry() ;
			sum.parent = null ;
			sum.freq = left.freq + right.freq ;
			sum.left = left ; 
			sum.right = right ;
			left.parent = sum ;
			right.parent = sum ;
			
			pq.add(sum) ;    //将左右子节点的频率之和成为其父节点,并添加到优先级队列中
		}
	}
	
	//解码
	public void calculateHuffmanCodes()
	{
        	String code;
        	Entry entry;
        	for (int i = 0; i < SIZE; i++)
        	{
            		code = "";
            		entry = leafEntries [i];
            		if (entry.freq > 0)
            		{
                		while (entry.parent != null)
                 		{
                      			code = entry.code + code;   
                      			entry = entry.parent;       
                 		} // while                		
				        leafEntries [i].code = code;
            		} // if
        	} // for
	} // calculateHuffmanCodes

	public String getCodes()
	{
        	Entry entry;

        	String codes = new String();

        	for (int i = 0; i < SIZE; i++)
        	{
            		entry = leafEntries [i];
            		if (entry.freq > 0)
                		codes += (char)i + " " + entry.code + "\n";
        	} // for
        	return codes;
	} // method getCodes

 
    public String getEncodedLine (String line)
    {
        Entry entry;

        String encodedLine = new String();

        for (int j = 0; j < line.length(); j++)
        {
            	entry = leafEntries [(int)(line.charAt (j))];
            	encodedLine += entry.code;
        } // for
        entry = leafEntries [(int)'\r'];
        encodedLine += entry.code;
        return encodedLine;
	} // method getEncodedLine


} // class Huffman


class Entry implements Comparable<Entry> 
{
    	int freq;

    	String code;

    	char id;

    	Entry left,
              right,
              parent;

    	public int compareTo (Entry entry) 
    	{
        	return freq - entry.freq;
    	} // compareTo

} // class Entry


	 
package HUffman;

import java.io.*;

public class HuffmanTester
{

	protected BufferedReader fileReader;
	protected PrintWriter fileWriter;
	protected Huffman huffman;
	protected String inFilePath;

 	public HuffmanTester()
	{
        	huffman = new Huffman();
 	} // default constructor

	public PrintWriter openFiles()
	{
		final String IN_FILE_PROMPT =
          		"\nPlease enter the path for the input file: ";

      		final String OUT_FILE_PROMPT =
          		"\nPlease enter the path for the output file: ";

      		BufferedReader keyboardReader = new BufferedReader(new InputStreamReader (System.in));
                                          	
      		String outFilePath,
                       line;

      		boolean pathsOK = false;

      		while (!pathsOK)
      		{
          		try
          		{
              			System.out.print (IN_FILE_PROMPT);
              			inFilePath = keyboardReader.readLine();
              			fileReader= new BufferedReader(new FileReader (inFilePath));           		  	
              			System.out.print (OUT_FILE_PROMPT);
              			outFilePath = keyboardReader.readLine();
              			fileWriter = new PrintWriter (new FileWriter (outFilePath));
              			pathsOK = true;	
          		} // try
          		catch (IOException e)
          		{
              		System.out.println (e);
          		} // catch
        	} // while !pathOK
		return fileWriter;
	} // method openFiles


	 
	public void createEncoding()
	{
     		String line;

        	try
        	{
            		while (true)
            		{
                		line = fileReader.readLine();
                		if (line == null)
                    			break;
                		huffman.updateFrequencies (line);
            		} // while
            		fileReader.close(); // re-opened in saveEncodedMessage
            		huffman.createPQ();
            		huffman.createHuffmanTree();
            		huffman.calculateHuffmanCodes();
        	} // try
        	catch (IOException e)
        	{
            		System.out.println (e);
        	} // catch IOException
	} // method createEncoding

 
	public void saveEncodedMessage()
	{
        	String line;

        	try
        	{
           			fileWriter.print (huffman.getCodes());
            		fileWriter.println ("**"); // to separate codes from encoded message
            		fileReader = new BufferedReader (new FileReader (inFilePath));

            		while (true)
            		{
                		line = fileReader.readLine();
                		if (line == null)
                    			break;
                		fileWriter.println (huffman.getEncodedLine (line));
            		} // while            	
        	} // try
        	catch (IOException e)
        	{
            		System.out.println (e);
        	} // catch IOException
	} // method saveEncodedMessage

} // class HuffmanTester



package HUffman;
import java.io.*;
public class HuffmanTesterMain {
 
	public static void main(String[] args) {
		PrintWriter writer = null;
	       
  		try
  		{
       		HuffmanTester tester = new HuffmanTester();
       
       		writer = tester.openFiles();
       		tester.createEncoding();
			tester.saveEncodedMessage();
   		} // try
   		finally
   		{
       		writer.close();
		} // finally	


	}

}

 

输入字符的存储结构:

频率 编码 字符 parent left right
0
0
分享到:
评论

相关推荐

    哈弗曼树及编码 C语言实现

    在C语言下实现哈弗曼树的创建并进行哈弗曼编码,同时输出哈弗曼编码。

    哈弗曼树进行压缩编码

    6. **解压缩**:在解压时,读取存储的哈弗曼树或编码表,然后按照编码解码得到原始的字符流,再重新组合成原来的txt或doc文件。 在C++编程语言中实现哈弗曼编码,你需要定义数据结构来表示哈弗曼树节点,如包括字符...

    c++哈弗曼树的解码与编码

    5. **解码数据**:解码过程需要哈弗曼树和编码后的二进制数据。遍历二进制数据,每次根据当前位决定是向左还是向右移动,直到到达叶子节点,记录该叶子节点所代表的字符,并回到根节点继续解码剩余的二进制数据。 ...

    哈弗曼编码的编码解码

    在"霍夫曼编码"这个项目中,可能包含了实现这些功能的源代码文件,包括构造哈弗曼树、统计字符频率、生成哈弗曼编码和解码的算法。通过对这些代码的分析和学习,我们可以深入理解哈弗曼编码的工作原理,并能够实际...

    哈弗曼树编码解码程序

    根据给定文件的信息,我们可以总结出以下关于“哈弗曼树编码解码程序”的相关知识点: ### 一、概述 哈弗曼树(Huffman Tree)又称最优二叉树,是一种带权路径长度最短的二叉树。哈弗曼编码(Huffman Coding)是一...

    哈弗曼编码与解码

    构建哈弗曼树是整个编码过程的基础,具体步骤如下: 1. **初始化节点**:首先根据字符出现的频率初始化所有节点的权重,其余属性如左右子节点、父节点等设为0。 2. **选择与合并节点**:通过循环,每次选择两个...

    哈弗曼编码与解码实验报告

    5. **输入编码解码**: 解码时,需要再次遍历所有叶子节点,对输入的哈弗曼编码逐位与每个节点的编码进行比对。当输入编码与某个字符的哈弗曼编码完全匹配时,输出对应的字符。如果在比对过程中发现编码不匹配,...

    用哈弗曼树对文件进行编码和译码

    在实际应用中,哈弗曼树可以与其他算法结合使用,例如 LZ77、LZW 等,以提高压缩比和编码速度。 在哈弗曼树的实现中,需要注意以下几点: * 需要选择合适的数据结构来存储哈弗曼树 * 需要合理地选择哈弗曼树的建立...

    利用哈弗曼树实现编码译码

    哈弗曼编码是一种高效的数据压缩方法,它基于一种特殊的二叉树——哈弗曼树(Huffman Tree),也称为最优二叉树。在MFC(Microsoft Foundation Classes)框架下,我们可以构建用户界面来实现哈弗曼编码和解码的过程...

    哈弗曼树编码课程设计

    哈弗曼树编码是一种高效的前缀编码方法,广泛应用于数据压缩和通信领域。在这个课程设计中,我们将深入探讨哈弗曼编码的原理、构建过程以及如何实现编码与译码功能,同时支持文件的读写操作。 哈弗曼树,又称为最优...

    哈弗曼树的建立及哈弗曼编码的生成 c++实现

    哈弗曼树(Huffman Tree),也称为最优二叉树,是数据结构中的一种特殊二叉树,主要用于数据的编码和解码,特别是在文本压缩中起到关键作用。它通过一种贪心策略构建,使得带权路径长度最短,从而达到编码效率最高。...

    用C语言实现的哈弗曼树的解码以及编码

    用C语言实现的哈弗曼树的解码以及编码,读入文件编码后保存为另外一个文件。

    数据结构实验 哈弗曼树及其编码译码

    哈弗曼树的构建过程基于哈夫曼编码,它是一种前缀编码,即任何字符的编码都不会是其他字符编码的前缀,这确保了编码的唯一性。 在哈夫曼树的构建过程中,首先需要统计信源中各符号(通常为字符)出现的概率。这些...

    基于M进制哈弗曼编码解码程序

    解码过程中,通常需要维护一个哈弗曼树结构,以便根据输入的M进制编码找到对应的字符。如果哈弗曼树的构建或遍历方式不够优化,可能会导致解码速度较慢。 为了改善解码效率,可以从以下几个方面着手: 1. **优化...

    用C++语言写的关于用哈弗曼树编码问题的程序

    哈弗曼编码是一种高效的数据压缩方法,它利用了字符出现频率的不同来构建最优的二叉树,也称为哈弗曼树。在这个C++程序中,我们将会深入理解哈弗曼编码的原理及其在实际编码过程中的应用。 首先,我们要知道哈弗曼...

    哈弗曼树实验编码 有五个功能

    给定一个哈弗曼编码,我们需要根据哈弗曼树来解码。从根节点出发,按照编码中的“0”和“1”沿着树的分支移动,当到达叶子节点时,就找到了对应的字符或数据元素。这个过程需要哈弗曼树结构作为参考。 4. **显示码...

    哈弗曼树的生成(编码)

    哈弗曼树,又称霍夫曼树,是一种特殊的二叉树,主要用于数据的高效编码,尤其是在数据压缩领域有着广泛的应用。这种树结构的特点是:树中任一节点的两个子节点都是子树中权值最小的两个节点。权值在这里通常代表字符...

Global site tag (gtag.js) - Google Analytics