构造哈夫曼树时使用双亲孩子的存储结构,需要数据有: 权重,他们母亲是谁,是否加入了哈夫曼树,他们左孩子与右孩子又是谁?
步骤:
- 单节点的初始化入哈夫曼树中,初始化2*n-1个节点
- 寻找两个权重最小且还没有加入树中的节点进行构造哈夫曼树,不断重复此过程(构造过程中存储结构中变动的信息都需要更新)其实这寻找两个权值最小的节点挺难的,困了好长时间/(ㄒoㄒ)/~~
- 根据构造的树,解析析出哈夫曼编码
双亲孩子节点
上图把head换成leftchild 和 rightchild就可以代表仿真指针实现的双亲孩子的储存结构
get了一个新技巧,对于一个数组中胡乱的加入各个大小的数据,怎么循环一次就可以把其中最小的和次小的下标找到,分两个情况考虑:
- 最小值在次小值右边,想象着最小值在最右边,一直遍历下去定会也遇到次小值
- 最小值在次小值左边,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int big1=9999, big2=9999, index1 = 0, index2 = 0;
for(int j=0;j<n+i;j++) { if(big1>tree[j].weight && tree[j].flag==0) { big2=big1; index2=index1; big1=tree[j].weight; index1=j; } else if(big2>tree[j].weight && tree[j].flag==0 ) { big2=tree[j].weight; index2=j; } }
|
源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| import java.util.ArrayList;
public class HuffmanCoding { static int weight[]=new int[] {1,3,5,7}; public static void main(String[] args) { hufftree tree[]=new hufftree[weight.length*2-1]; for(int i=0;i<tree.length;i++) tree[i]=new hufftree(); haffman(weight,tree); huffcode code[]=new huffcode[weight.length]; for(int i=0;i<weight.length;i++) code[i]=new huffcode(); generateHuffCode(tree,code); for(int i=0;i<code.length;i++) { ArrayList<Integer> a=code[i].code; String s=""; for(int j=a.size()-1;j>=0;j--) { s+=a.get(j); } System.out.println(code[i].weight+" :"+s); } System.out.println(123); } private static void generateHuffCode(hufftree[] tree, huffcode[] code) { for(int i=0;i<code.length;i++) { int parents=tree[i].parents; int child=i; int weight=tree[i].weight; code[i].weight=weight; while(parents!=-1) { if(tree[parents].leftchild==child) code[i].code.add(0); else code[i].code.add(1); child=parents; parents=tree[child].parents; } } }
static void haffman(int weight[],hufftree tree[]) { int n=weight.length; for(int i=0;i<tree.length;i++) { if(i<n) tree[i].weight=weight[i]; else tree[i].weight=0; tree[i].flag=0; tree[i].parents=-1; tree[i].leftchild=-1; tree[i].rightchild=-1; } for(int i=0;i<n-1;i++) { int big1=9999, big2=9999, index1 = 0, index2 = 0; for(int j=0;j<n+i;j++) { if(big1>tree[j].weight && tree[j].flag==0) { big2=big1; index2=index1; big1=tree[j].weight; index1=j; } else if(big2>tree[j].weight && tree[j].flag==0 ) { big2=tree[j].weight; index2=j; } } tree[index1].parents=n+i; tree[index2].parents=n+i; tree[index1].flag=1; tree[index2].flag=1; tree[n+i].weight=tree[index1].weight+tree[index2].weight; tree[n+i].leftchild=index1; tree[n+i].rightchild=index2; } } } class huffcode{ ArrayList<Integer> code=new ArrayList<Integer>(); int weight; }
class hufftree{ int weight, flag, parents, leftchild, rightchild; }
|