#include<stdio.h>
#include<stdlib.h>
struct node {
char c;
float p;
int lchild;
int rchild;
int parent;
int index;
};
void swap(node& a, node& b) {
node temp;
temp = a;
a = b;
b = temp;
}
void minHeapify(node arr[], int n, int i) {
int smallest = i; // 初始化根节点为最小值
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节dian
// 如果左子节点小于根节点,将其设为最小值
if (left < n && arr[left].p < arr[smallest].p)
smallest = left;
// 如果右子节点小于当前最小值,将其设为最小值
if (right < n && arr[right].p < arr[smallest].p)
smallest = right;
// 如果最小值不是根节点,交换根节点与最小值的位置,并进行递归调整
if (smallest != i) {
swap(arr[i], arr[smallest]);
minHeapify(arr, n, smallest);
}
}
// 生成最小堆
void make_heap(node arr[], int n) {
int i;
// 从最后一个非叶节点开始向上调整每个节点
for (i = n / 2 - 1; i >= 0; i--)
minHeapify(arr, n, i);
}
// 删除最小元素并调整为新的最小堆
node delete_min(node H[], int& n) {
node min = H[0];
H[0] = H[n - 1];
n = n - 1;
minHeapify(H, n, 0);
return min;
}
void insert(node H[], int& n, node x) {
n = n + 1;
H[n-1] = x;
int i = n-1;
bool done = false;
while (!done && i != 0) {
if (H[i].p < H[i / 2].p)
swap(H[i], H[i / 2]);
else done = true;
i = i / 2;
}
}
void Huffman(char C[], float p[], int n, struct node T[], node H[]) {
struct node x, y, u;
int i, m = n;
//初始化T,H
for (i = 0; i < n; i++) {
T[i].c = H[i].c = C[i];
T[i].p = H[i].p = p[i];
T[i].lchild = T[i].rchild = T[i].parent = -1;
H[i].index = i;
}
make_heap(H, n);
for (i = 0; i < n - 1; i++) {
x = delete_min(H, m);
y = delete_min(H, m);
u.p = x.p + y.p;
u.index = n + i;
insert(H, m, u);
T[n + i].lchild = x.index;
T[n + i].rchild = y.index;
T[n + i].parent = -1;
T[x.index].index = 0;
T[y.index].index = 1;
T[x.index].parent = T[y.index].parent = n + i;
}
}
int main() {
int n = 8;
char C[8] = { 'a','b','c','d','e','f','g','h' };
float p[8] = { 43,23,16,8,5,2,2,1 };
node T[15], H[8],x;//T存放二叉树结点,H存放二叉树相关结点的堆
Huffman(C, p, n, T, H);
for (int i = 0; i < 8; i++) {//输出的实际是逆序
x = T[i];
printf("%c:\t", x.c);
while (x.parent != -1) {
printf("%d",x.index);
x = T[x.parent];
}
printf("\n");
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
//测试huffman编码
void swap0(int& a, int& b) {
int temp;
temp = a;
a = b;
b = temp;
}
void minHeapify0(int arr[], int n, int i) {
int smallest = i; // 初始化根节点为最小值
int left = 2 * i + 1; // 左子节点
int right = 2 * i + 2; // 右子节dian
// 如果左子节点小于根节点,将其设为最小值
if (left < n && arr[left] < arr[smallest])
smallest = left;
// 如果右子节点小于当前最小值,将其设为最小值
if (right < n && arr[right] < arr[smallest])
smallest = right;
// 如果最小值不是根节点,交换根节点与最小值的位置,并进行递归调整
if (smallest != i) {
swap0(arr[i], arr[smallest]);
minHeapify0(arr, n, smallest);
}
}
// 生成最小堆
void make_heap0(int arr[], int n) {
int i;
// 从最后一个非叶节点开始向上调整每个节点
for (i = n / 2 - 1; i >= 0; i--)
minHeapify0(arr, n, i);
}
// 删除最小元素并调整为新的最小堆
int delete_min0(int H[], int& n) {
int min = H[0];
H[0] = H[n - 1];
n = n - 1;
minHeapify0(H, n, 0);
return min;
}
void insert0(int H[], int& n, int x) {
n = n + 1;
H[n - 1] = x;
int i = n - 1;
bool done = false;
while (!done && i != 0) {
if (H[i] < H[i / 2])
swap0(H[i], H[i / 2]);
else done = true;
i = i / 2;
}
}
int main() {
int n = 8;
int p[8] = { 43,23,16,8,5,2,2,1 },t[15];
make_heap0(p, n);
for (int i = 0; i < n; i++) {
t[i]=p[i];
}
for (int i = 0; i < 7; i++) {
int x = delete_min0(p, n);
int y = delete_min0(p, n);
int u = x + y;
t[8 + i] = u;
insert0(p, n, u);
}
for (int i = 0; i < 15; i++){
printf("%d\t", t[i]);
}
/*printf("\n");
printf("%d,%d,%d,%d", c, ce, cd, n);
for (int i = 0; i < n; i++) {
printf("%d\t", p[i]);}*/
return 0;
}