哈夫曼树

  定义:哈夫曼树也叫最优二叉树,指WPL最小的二叉树。

  WPL(带权路径长度):二叉树中所有叶子结点的权值与从该结点到根结点的长度积之和

 

  特点:

  无度为1的结点

  哈夫曼树中任意非叶结点的左右子树交换后仍为哈夫曼树

 

  哈夫曼树的构建:

  将权值排序,每次将权值最小的两棵二叉树合并

 

  1 #include 
  2 #include 
  3 
  4 struct node {
  5     int weight;
  6     struct node* lson;
  7     struct node* rson;
  8 };
  9 typedef struct node* tree;
 10 
 11 #define maxSize 100
 12 struct {
 13     tree array[maxSize];
 14     int num;
 15 } heap;
 16 
 17 tree buildTree(int n);
 18 int caculateWPL(tree root, int step);
 19 void mypush(int w);
 20 void push(tree newnode);
 21 tree pop();
 22 void up(int index);
 23 void down(int index);
 24 void swap(int index1, int index2);
 25 
 26 int main() {
 27     //读取n个权值,并将其压入堆
 28     int n;
 29     scanf("%d", &n);
 30     int i;
 31     for (i = 0; i < n; ++i) {
 32         int t;
 33         scanf("%d", &t);
 34         mypush(t);
 35     }
 36 
 37     //构建哈夫曼树
 38     tree root = buildTree(n);
 39 
 40     //计算权值并将其输出
 41     int WPL = caculateWPL(root, 0);
 42     printf("%d\n", WPL);
 43 
 44     return 0;
 45 }
 46 
 47 tree buildTree(int n) {
 48     tree root = NULL;
 49     int i;
 50     //进行n-1次合并
 51     for (i = 1; i < n; ++i) {
 52         tree newnode = (tree)malloc(sizeof(struct node));
 53         newnode -> lson = pop();
 54         newnode -> rson = pop();
 55         newnode -> weight = newnode->lson->weight + newnode->rson->weight;
 56 
 57         //将生成的新树压入堆
 58         push(newnode);
 59     }
 60 
 61     //堆中剩余的元素为哈夫曼树的根结点
 62     root = pop();
 63 
 64     return root;
 65 }
 66 
 67 int caculateWPL(tree root, int step) {
 68     int ans = 0;
 69     if ((root->lson == NULL) && (root->rson == NULL)) {
 70         ans = root->weight * step;
 71     }
 72     else {
 73         if (root->lson) {
 74             ans += caculateWPL(root->lson, step+1);
 75         }
 76         if (root->rson) {
 77             ans += caculateWPL(root->rson, step+1);
 78         }
 79     }
 80     free(root);
 81 
 82     return ans;
 83 }
 84 
 85 //将初始权值压入堆
 86 void mypush(int w) {
 87     ++heap.num;
 88     tree newnode = (tree)malloc(sizeof(struct node));
 89     newnode -> weight = w;
 90     newnode -> lson = NULL;
 91     newnode -> rson = NULL;
 92     heap.array[heap.num] = newnode;
 93     up(heap.num);
 94 }
 95 
 96 //将一个新结点压入堆
 97 void push(tree newnode) {
 98     ++heap.num;
 99     heap.array[heap.num] = newnode;
100     up(heap.num);
101 }
102 
103 //将堆顶弹出
104 tree pop() {
105     tree t = heap.array[1];
106     heap.array[1] = heap.array[heap.num];
107     heap.array[heap.num] = NULL;
108     --heap.num;
109     down(1);
110 
111     return t;
112 }
113 
114 //堆的上浮操作
115 void up(int index) {
116     while (index / 2 > 0) {
117         if (heap.array[index]->weight < heap.array[index/2]->weight) {
118             swap(index, index/2);
119             index /= 2;
120         }
121         else {
122             break;
123         }
124     }
125 }
126 
127 //堆的下沉操作
128 void down(int index) {
129     while (index * 2 <= heap.num) {
130         int minSon = index * 2;
131         if (minSon+1 <= heap.num && heap.array[minSon+1]->weight < heap.array[minSon]->weight) {
132             ++minSon;
133         }
134         if (heap.array[index]->weight > heap.array[minSon]->weight) {
135             swap(index, minSon);
136             index = minSon;
137         }
138         else {
139             break;
140         }
141     }
142 }
143 
144 //交换堆中的两个元素
145 void swap(int index1, int index2) {
146     tree t = heap.array[index1];
147     heap.array[index1] = heap.array[index2];
148     heap.array[index2] = t;
149 }

 

你可能感兴趣的:(哈夫曼树)