用Java采用树形结构实现HuffmanTree(附录代码)

1 篇文章 0 订阅

首先Huffman的原理,即每次选取出现次数最少的两个建立一颗新树,然后再循环,由此可知,一共需要循环n-1次,n即总的节点数,就可以建立起一颗Huffman树。

了解了原理后,现在来看代码:(主要以建立Huffman编码树的例子来讲)

1、首先,要建立树结点,来储存一些必要的信息。

public static class HuffmanNode{
		public char data;//节点的内容
		public int time;//该节点出现的次数
		public HuffmanNode left;//左孩子
		public HuffmanNode right;//右孩子
		public int ceng=0;//层数,用于直观显示
	}

2、进行构造

//构造HuffmanTree的初始化函数
	public static HuffmanNode initHuffmanTree(int times[],char []datas ){
		int n=times.length;
		HuffmanNode huffmanNodes[]=new HuffmanNode[n];
		HuffmanNode[] temp=new HuffmanNode[n];
		for(int i=0;i<n;i++){
			temp[i]=new HuffmanNode();
			huffmanNodes[i]=new HuffmanNode();
			huffmanNodes[i].data=datas[i];
			huffmanNodes[i].time=times[i];
			huffmanNodes[i].left=null;
			huffmanNodes[i].right=null;
		}
		//先对整体排次序(本代码采用归并排序,且降序排列)
		sort(huffmanNodes, 0, n-1, temp);
		//进行n-1次的构造
		for(int i=n-1;i>=1;i--){
			//当前最小
			HuffmanNode min1=huffmanNodes[i];
			HuffmanNode min2=huffmanNodes[i-1];
			HuffmanNode newNode=new HuffmanNode();
			huffmanNodes[i]=null;
			newNode.data='$';
			newNode.time=min1.time+min2.time;
			newNode.left=min1;
			newNode.right=min2;
			huffmanNodes[i-1]=newNode;
			//对剩下的再进行排序
			sort(huffmanNodes, 0, i-1, temp);
		}
		return huffmanNodes[0];
	}

注:传入参数:times就是题目所给的各个叶子节点的出现次数,datas指各个叶子节点的内容。

排序方法多种多样,只要实现降序排列即可。为什么要降序?因为本代码采用的思想是:每次选取最后面的两个,即最小值和次小值,然后就把新生成的节点放在次小值位置上,最小值位置置为null,只要从后往前循环结束后,下标0处即最终的根节点

3、排序方法:给出归并排序的实现

//归并排序的两个方法1
	private static void sort(HuffmanNode[] huffmanNodes,int left,int right,HuffmanNode []temp){
		if(left<right){
			int middle=(left+right)/2;
			sort(huffmanNodes, left, middle, temp);
			sort(huffmanNodes, middle+1, right, temp);
			merge(huffmanNodes, left, right, middle, temp);
		}
	}
	//归并排序的两个方法2
	private static void merge(HuffmanNode[] huffmanNodes,int left,int right,int middle,HuffmanNode []temp){
		int i=left;
		int j=middle+1;
		int t=0;
		while(i<=middle && j<=right){
			if(huffmanNodes[i].time>=huffmanNodes[j].time){
				temp[t++]=huffmanNodes[i++];
			}
			if(huffmanNodes[i].time<huffmanNodes[j].time){
				temp[t++]=huffmanNodes[j++];
			}
		}
		while(i<=middle){
			temp[t++]=huffmanNodes[i++];
		}
		while(j<=right){
			temp[t++]=huffmanNodes[j++];
		}
		t=0;
		while(left<=right){
			huffmanNodes[left++]=temp[t++];
		}
	}

4、最终按照层序遍历将树遍历出来。在遍历的过程中,给其层数赋值,即父亲节点层数加一

//层序遍历HuffmanTree
	public static void show(HuffmanNode root){
		Queue<HuffmanNode> queue=new LinkedList<>();
		root.ceng=0;
		System.out.println(root.data+" "+root.time+" "+root.ceng);
		if(root.left!=null) {
			root.left.ceng=root.ceng+1;
			queue.add(root.left);
		}
		if(root.right!=null) {
			root.right.ceng=root.ceng+1;
			queue.add(root.right);
		}
		while(queue.size()!=0){
			HuffmanNode huffmanNode=queue.poll();
			System.out.println(huffmanNode.data+" "+huffmanNode.time+" "+huffmanNode.ceng);
			if(huffmanNode.left!=null) {
				huffmanNode.left.ceng=huffmanNode.ceng+1;
				queue.add(huffmanNode.left);
			}
			if(huffmanNode.right!=null) {
				huffmanNode.right.ceng=huffmanNode.ceng+1;
				queue.add(huffmanNode.right);
			}
		}
		
	}

5、主要功能已经完成,将以上所有代码均放入道HuffmanTree类中,然后新建主函数测试

public class Main {
	public static void main(String args[]){
		int times[]={3 ,4, 10, 8, 6 ,5};
		char datas[]={'A','B','C','D','E','F'};
		HuffmanTree.HuffmanNode root=HuffmanTree.initHuffmanTree(times, datas);
		HuffmanTree.show(root);
	}

}

6、结果:$表示是自己添加的节点 输出格式为: data  time  层数

$ 36 0
$ 15 1
$ 21 1
$ 7 2
D 8 2
C 10 2
$ 11 2
A 3 3
B 4 3
F 5 3
E 6 3

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值