数据结构之哈夫曼树(java实现)-(五)

28 篇文章 2 订阅

    所谓哈夫曼树就是要求最小加权路径长度,这是什么意思呢?简而言之,就是要所有的节点对应的路径长度(高度-1)乘以该节点的权值,然后保证这些结果之和最小。

   哈夫曼树最常用的应用就是解决编码问题。一般我们用的ASCII是固定长度的编码,对于那些常用的字符,使用很长的长度就显得略为浪费空间了。

  下面以一个实例来构建一颗哈夫曼编码树。

   设字符集S={A,B,C,D,E,F},字符出现的频率W={2,3,5,7,9,12},对字符集进行哈夫曼编码

   (1)以频率为树的节点值,构建6个树节点,保存在一个数据集合T中

     (2)选择频率集W中最小的两个频率,然后相加,将结果作为树的节点值,构建新的树节点,将这两个最小值对应的树节点,分别作为新的节点的左右孩子。从T重删除这两个最小值对应的节点,最后将新节点放到T中。

   (3)重复第2步,直到T中只剩下一个节点,那么该节点就是所需要的哈夫曼树

 其实说的容易,实现起来也有一点小麻烦,下面用java实现:

     树节点:

              

public class TreeNode<T>
	{
        public TreeNode<T> leftNode;
        public TreeNode<T> rightNode;
        public T data;
		public TreeNode(T data)
			{
				this.data=data;
			}
	}
   构建哈夫曼树:

public class TestTree
	{
		/*
		 * 设S={A,B,C,D,E,F},W={2,3,5,7,9,12}
		 */
		static HashMap<Character, Integer> map;
		public TestTree()
			{
				// TODO Auto-generated constructor stub
			}

		public static void main(String[] args)
			{
				Character[] character = { 'A', 'B', 'C', 'D', 'E', 'F' };
				int[] weight = { 2, 3, 5, 7, 9, 12 };// 有序或者无序都一样
				map=new HashMap<Character, Integer>();
				for(int i=0;i<weight.length;i++)
					map.put(character[i], weight[i]);
				
				ArrayList<TreeNode<Integer>> nodes = new ArrayList<TreeNode<Integer>>();
				for (int i = 0; i < weight.length; i++)
					{
						nodes.add(new TreeNode<Integer>(weight[i]));
					}
				while (true)
					{
						if (nodes.size() <= 1)
							break;
						// 找两个最小的
						TreeNode<Integer> minNode = nodes.get(0);
						TreeNode<Integer> sminNode = nodes.get(1);
						for (int i = 1; i < nodes.size(); i++)
							{
								TreeNode<Integer> tempNode = nodes.get(i);
								if (minNode.data >=tempNode.data)
									{
										sminNode = minNode;
										minNode = tempNode;
									}
							}
						nodes.remove(minNode);
						nodes.remove(sminNode);
						TreeNode<Integer> newNode = new TreeNode<Integer>(
								minNode.data + sminNode.data);
						newNode.leftNode = minNode;
						newNode.rightNode = sminNode;
						nodes.add(newNode);
					}
				TreeNode<Integer>hafmanTreeNode=nodes.get(0);
				getHalmanCode(hafmanTreeNode," ");
				
			}
		 public static void getHalmanCode(TreeNode<Integer>hafmanTreeNode,String blank)
		 {
			 if(hafmanTreeNode==null)
				 return;
			 if(hafmanTreeNode.leftNode==null&&hafmanTreeNode.rightNode==null)
				 {
				   System.out.println("->"+getCharacter(hafmanTreeNode.data));
				 }
			 else 
				 {
					 System.out.print("0");
					 getHalmanCode(hafmanTreeNode.leftNode,blank+" ");
					 System.out.print(blank+"1");
					 getHalmanCode(hafmanTreeNode.rightNode,blank+" ");
				 }
		 }
		 //得到某一个字符的编码
		 public static void getHalmanCode(TreeNode<Integer>hafmanTreeNode,Character character)
		 {
			 if(hafmanTreeNode==null)
				 return;
			 if(hafmanTreeNode.leftNode==null&&hafmanTreeNode.rightNode==null)
				 {
					 if (getCharacter(hafmanTreeNode.data)==character)
						{
							System.out.print("");
						}
				 }
		 }
                //得到权值对应的字符
		 public static Character getCharacter(int weight)
		 {
			 Set<Map.Entry<Character, Integer>>set=map.entrySet();
			 for(Iterator<Map.Entry<Character, Integer>> iterator=set.iterator();iterator.hasNext();)
				 {
					 Map.Entry<Character, Integer>entry=iterator.next();
					 if(entry.getValue()==weight)
						 {
							 map.remove(entry.getKey());
							 return entry.getKey();
						 }
				 }
			 return null;
		 }
	}
  结果:

       

 D:00

 E:01

 A:1000

 B:1001

 C:101

 F:11

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值