哈夫曼树
定义:哈夫曼树也叫最优二叉树,指WPL最小的二叉树。
WPL(带权路径长度):二叉树中所有叶子结点的权值与从该结点到根结点的长度积之和
特点:
无度为1的结点
哈夫曼树中任意非叶结点的左右子树交换后仍为哈夫曼树
哈夫曼树的构建:
将权值排序,每次将权值最小的两棵二叉树合并
1 #include <stdio.h> 2 #include <stdlib.h> 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 }

浙公网安备 33010602011771号