本代码是由java代码实现
什么是哈夫曼树,怎么构造:
假设给定权值:2, 3, 7, 9, 18, 25
那么构造出的树直观上应该是这样:
实现步骤
第一步:
使用两个最小的权值 2 3 构造树(小的放在左子树,大的放在右子树)
此时 权值删除 2 3 加入 5 并且进行排序
权值为:5, 7, 9, 18, 25
第二步:
使用两个最小的权值 5 7 构造树(小的放在左子树,大的放在右子树)
此时 权值删除 5 7 加入 12 并且进行排序
权值为: 9,12, 18, 25
第三步:
使用两个最小的权值 9 12 构造树(小的放在左子树,大的放在右子树)
此时 权值删除 9 12 加入 21 并且进行排序
权值为: 18,21, 25
第四步:
使用两个最小的权值 18 21 构造树(小的放在左子树,大的放在右子树)
此时 权值删除 18 21 加入 39 并且进行排序
权值为: 25,39
第五步:
使用两个最小的权值 25 39 构造树(小的放在左子树,大的放在右子树)
此时哈夫曼树就建好了,这就是哈夫曼树的思想。
下面根据思想代码实现,
首先:创建HuffmanTreeNode(哈夫曼树节点类)
public class HuffmanTreeNode { /** * 每个哈夫曼树节点的权值 */ public int weight; /** * 标志着是否进行构成一个哈夫曼树 */ public int flag; /** * 定义节点父亲 左孩子 右孩子 */ public HuffmanTreeNode lChild, rChild; public HuffmanTreeNode() { } public HuffmanTreeNode(int weight) { this.weight = weight; } }
然后写HuffmanTree(构造Huffman树)类
public class HuffmanTree { public HuffmanTreeNode creatHuffmanTree(int[] w){ int n = w.length; //构建哈夫曼树一共需要的节点个数 int m = n * 2 - 1; //创建一个 哈曼树节点数组 里面存放哈夫曼节点 HuffmanTreeNode[] htn = new HuffmanTreeNode[m]; int i; for(i = 0; i < n; i++) { htn[i] = new HuffmanTreeNode(w[i]); } //开始构建哈夫曼树 for(i = n; i < m; i++) { //这个方法实现找出权值最小的节点的 HuffmanTreeNode min1 = selectMin(htn,i - 1); //flag设置为1 标志着构造哈夫曼树使用了这个权值 min1.flag = 1; //继续找出 HuffmanTreeNode min2 = selectMin(htn,i - 1); min2.flag = 1; //构建哈夫曼树 htn[i] = new HuffmanTreeNode(); htn[i].weight = min1.weight + min2.weight; //父节点左右子节点 小的放左边 大的放右边 htn[i].lChild = min1; htn[i].rChild = min2; } //此时 i = 11 但是哈夫曼节点数组长度长为11 下标只能为10 为11的时候越界 // 所以返回的时候应该返回 i-1处的节点 此节点就是哈夫曼树的根节点 return htn[i-1]; } //在【0 - end 中找出权值最小的节点】 public HuffmanTreeNode selectMin(HuffmanTreeNode[] htn, int end) { int j = 0; //找出HuffmanTreeNode数组当中 HuffmanTreeNode 类中的 flag属性为0的 元素 for( j = 0; j <= end; j++) { if(htn[j].flag == 0) { break; } } //定义一个新变量 用于保存最小的权值的类 HuffmanTreeNode min = htn[j]; for(int i = 0; i <= end; i++) { HuffmanTreeNode curNode = htn[i]; if(curNode.flag == 0 && curNode.weight < min.weight) { min = curNode; } } return min; } }
然后使用HuffmanTest(哈夫曼树测试)类验证并且附带层次遍历和前序遍历输出:
import java.util.LinkedList; import java.util.Queue; /* 构造哈夫曼树 给出以下权重2, 3, 7, 9, 18, 25,构造哈夫曼树。 以先序遍历方式输出节点,换行隔开。 注意:构造哈夫曼树时,节点值小的在左侧。 */ public class HuffmanTest { public static void main(String[] args) { int[] w = {2, 3, 7, 9, 18, 25}; HuffmanTree t = new HuffmanTree(); HuffmanTreeNode root = t.creatHuffmanTree(w);//构造哈夫曼树 System.out.println("构造哈夫曼树的层次遍历结果(换行打印):"); //构造的哈夫曼树进行层次遍历 levelOrder(root); System.out.print("构造哈夫曼树的前序遍历结果: "); //哈夫曼树进行前序遍历 prevOrder(root); System.out.println(); } public static void levelOrder(HuffmanTreeNode root) { Queue<HuffmanTreeNode> queue = new LinkedList<HuffmanTreeNode>();//创建队列 if(root == null) { return; } HuffmanTreeNode theLast = root;//theLast 存放所在层的最后一个树节点 HuffmanTreeNode nextLast = root;//存放下一层的最后一个树节点 HuffmanTreeNode temp;//用于存放队列头元素的地址 queue.add(root); while (queue.peek() != null) { temp = queue.poll(); System.out.print(temp.weight + " "); if(temp.lChild != null) { queue.add(temp.lChild); nextLast = temp.lChild; } if(temp.rChild != null) { queue.add(temp.rChild); nextLast = temp.rChild; } if(theLast == temp) //判断是否到达当前层的最后一个节点 { System.out.println();//换行 theLast = nextLast; } } } public static void prevOrder(HuffmanTreeNode root) { if(root == null) { return; } System.out.print(root.weight + " "); prevOrder(root.lChild); prevOrder(root.rChild); } }
以上就是哈夫曼树实现,觉得可以的话可以关注走一手