add
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_TREE_HT 256
|
||||
|
||||
// 定义 Huffman 树的节点结构
|
||||
typedef struct Node {
|
||||
int weight; // 节点的权重,即字符的频率
|
||||
char data; // 存储字符
|
||||
struct Node *left, *right; // 左右子节点
|
||||
} Node;
|
||||
|
||||
// 比较函数,用于 qsort 按照权重排序
|
||||
int compare(const void* a, const void* b) {
|
||||
return (*(Node**)a)->weight - (*(Node**)b)->weight;
|
||||
}
|
||||
|
||||
// 创建一个新的节点
|
||||
Node* newNode(char data, int weight) {
|
||||
Node* temp = (Node*)malloc(sizeof(Node));
|
||||
temp->left = temp->right = NULL;
|
||||
temp->data = data;
|
||||
temp->weight = weight;
|
||||
return temp;
|
||||
}
|
||||
|
||||
// 构建 Huffman 树
|
||||
Node* buildHuffmanTree(char data[], int weight[], int size) {
|
||||
// 创建一个指向节点的数组
|
||||
Node** nodeArr = (Node**)malloc(size * sizeof(Node*));
|
||||
// 将每个字符及其权重转化为节点并存入数组
|
||||
for (int i = 0; i < size; ++i) {
|
||||
nodeArr[i] = newNode(data[i], weight[i]);
|
||||
}
|
||||
// 使用 qsort 按照权重排序节点
|
||||
qsort(nodeArr, size, sizeof(Node*), compare);
|
||||
// 构建 Huffman 树
|
||||
while (size > 1) {
|
||||
// 取出两个最小的节点
|
||||
Node* left = nodeArr[0];
|
||||
Node* right = nodeArr[1];
|
||||
// 创建一个新的父节点,权重为两个子节点的权重之和
|
||||
Node* parent = newNode('\0', left->weight + right->weight);
|
||||
parent->left = left;
|
||||
parent->right = right;
|
||||
// 将父节点插入到 heap 中
|
||||
nodeArr[0] = parent;
|
||||
nodeArr[1] = nodeArr[size - 1]; // 将最后一个节点放到第二个位置
|
||||
size--;
|
||||
// 重新排序数组
|
||||
qsort(nodeArr, size, sizeof(Node*), compare);
|
||||
}
|
||||
Node* root = nodeArr[0];
|
||||
free(nodeArr);
|
||||
return root;
|
||||
}
|
||||
|
||||
// 打印 Huffman 编码
|
||||
void printHuffmanCodes(Node* root, int arr[], int top, char* codes[]) {
|
||||
if (root->left) {
|
||||
arr[top] = 0;
|
||||
printHuffmanCodes(root->left, arr, top + 1, codes);
|
||||
}
|
||||
|
||||
if (root->right) {
|
||||
arr[top] = 1;
|
||||
printHuffmanCodes(root->right, arr, top + 1, codes);
|
||||
}
|
||||
|
||||
// 如果是叶节点,打印字符和对应的编码
|
||||
if (!root->left && !root->right) {
|
||||
codes[root->data] = (char*)malloc((top + 1) * sizeof(char));
|
||||
if (!codes[root->data]) {
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
exit(1);
|
||||
}
|
||||
for (int i = 0; i < top; ++i)
|
||||
codes[root->data][i] = '0' + arr[i];
|
||||
codes[root->data][top] = '\0';
|
||||
printf("%c: %s\n", root->data, codes[root->data]);
|
||||
}
|
||||
}
|
||||
|
||||
// 获取字符的 Huffman 编码
|
||||
const char* getHuffmanCode(Node* root, char ch, int arr[], int top, char* codes[]) {
|
||||
if (codes[ch])
|
||||
return codes[ch];
|
||||
|
||||
if (root->left) {
|
||||
arr[top] = 0;
|
||||
const char* code = getHuffmanCode(root->left, ch, arr, top + 1, codes);
|
||||
if (code)
|
||||
return code;
|
||||
}
|
||||
|
||||
if (root->right) {
|
||||
arr[top] = 1;
|
||||
const char* code = getHuffmanCode(root->right, ch, arr, top + 1, codes);
|
||||
if (code)
|
||||
return code;
|
||||
}
|
||||
|
||||
// 如果是叶节点,检查是否是我们要找的字符
|
||||
if (!root->left && !root->right && root->data == ch) {
|
||||
codes[root->data] = (char*)malloc((top + 1) * sizeof(char));
|
||||
if (!codes[root->data]) {
|
||||
fprintf(stderr, "Memory allocation failed\n");
|
||||
exit(1);
|
||||
}
|
||||
for (int i = 0; i < top; ++i)
|
||||
codes[root->data][i] = '0' + arr[i];
|
||||
codes[root->data][top] = '\0';
|
||||
return codes[root->data];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// 编码函数:使用 Huffman 树编码文本
|
||||
void encode(Node* root, const char* str, char* encodedStr, char* codes[]) {
|
||||
int arr[MAX_TREE_HT], top = 0;
|
||||
printf("Huffman Codes:\n");
|
||||
printHuffmanCodes(root, arr, top, codes);
|
||||
|
||||
printf("\nEncoded Text: ");
|
||||
for (int i = 0; str[i] != '\0'; i++) {
|
||||
const char* code = getHuffmanCode(root, str[i], arr, 0, codes);
|
||||
if (code) {
|
||||
printf("%s", code);
|
||||
strcat(encodedStr, code); // 将每个字符的编码拼接到最终的编码字符串中
|
||||
} else {
|
||||
fprintf(stderr, "Character '%c' not found in Huffman tree\n", str[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 解码函数:从 Huffman 树解码编码文本
|
||||
void decode(Node* root, const char* encodedStr) {
|
||||
Node* current = root; // 从根节点开始
|
||||
printf("\nDecoded Text: ");
|
||||
|
||||
for (int i = 0; encodedStr[i] != '\0'; i++) {
|
||||
// 根据编码字符串的每个字符决定树的遍历方向
|
||||
if (encodedStr[i] == '0') {
|
||||
current = current->left; // 向左子节点移动
|
||||
} else if (encodedStr[i] == '1') {
|
||||
current = current->right; // 向右子节点移动
|
||||
}
|
||||
|
||||
// 如果到达叶节点,输出字符并返回根节点
|
||||
if (!current->left && !current->right) {
|
||||
printf("%c", current->data);
|
||||
current = root; // 重置为根节点,准备解码下一个字符
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// 释放 Huffman 树的内存
|
||||
void freeHuffmanTree(Node* node) {
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
freeHuffmanTree(node->left);
|
||||
freeHuffmanTree(node->right);
|
||||
free(node);
|
||||
}
|
||||
|
||||
// 释放 Huffman 编码的内存
|
||||
void freeHuffmanCodes(char* codes[]) {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (codes[i]) {
|
||||
free(codes[i]);
|
||||
codes[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
const char* text = "hello huffman coding";
|
||||
|
||||
// 计算每个字符的频率
|
||||
int freq[256] = {0};
|
||||
for (int i = 0; text[i] != '\0'; i++) {
|
||||
freq[(unsigned char)text[i]]++;
|
||||
}
|
||||
|
||||
// 构建字符和频率的数组
|
||||
char data[256];
|
||||
int frequencies[256];
|
||||
int size = 0;
|
||||
for (int i = 0; i < 256; i++) {
|
||||
if (freq[i] > 0) {
|
||||
data[size] = (char)i;
|
||||
frequencies[size] = freq[i];
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
// 构建 Huffman 树
|
||||
Node* root = buildHuffmanTree(data, frequencies, size);
|
||||
|
||||
// 初始化 Huffman 编码数组
|
||||
char* codes[256] = {NULL};
|
||||
|
||||
// 编码
|
||||
char encodedText[MAX_TREE_HT * strlen(text)];
|
||||
memset(encodedText, 0, sizeof(encodedText));
|
||||
encode(root, text, encodedText, codes);
|
||||
|
||||
// 解码
|
||||
decode(root, encodedText);
|
||||
|
||||
// 释放 Huffman 树的内存
|
||||
freeHuffmanTree(root);
|
||||
|
||||
// 释放 Huffman 编码的内存
|
||||
freeHuffmanCodes(codes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,100 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Node {
|
||||
int weight;
|
||||
struct Node *left, *right;
|
||||
} Node;
|
||||
|
||||
// 比较函数用于 qsort
|
||||
int compare(const void* a, const void* b) {
|
||||
return (*(Node**)a)->weight - (*(Node**)b)->weight;
|
||||
}
|
||||
|
||||
// 创建新节点
|
||||
Node* createNode(int weight) {
|
||||
Node* newNode = (Node*)malloc(sizeof(Node));
|
||||
newNode->weight = weight;
|
||||
newNode->left = newNode->right = NULL;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
// 构建哈夫曼树
|
||||
Node* createHuffmanTree(int* weights, int size) {
|
||||
Node** nodes = malloc(size * sizeof(Node*));
|
||||
for (int i = 0; i < size; i++) {
|
||||
nodes[i] = createNode(weights[i]);
|
||||
}
|
||||
while (size > 1) {
|
||||
qsort(nodes, size, sizeof(Node*), compare);// 排序节点数组
|
||||
// 创建父节点
|
||||
Node* parent = createNode(nodes[0]->weight + nodes[1]->weight);
|
||||
parent->left = nodes[0];
|
||||
parent->right = nodes[1];
|
||||
|
||||
// 替换前两个最小节点
|
||||
nodes[0] = parent;
|
||||
for (int i = 1; i < size - 1; i++) {
|
||||
nodes[i] = nodes[i + 1];
|
||||
}
|
||||
size--;
|
||||
}
|
||||
Node* root = nodes[0];
|
||||
free(nodes);
|
||||
return root;
|
||||
}
|
||||
|
||||
// 递归生成哈夫曼编码
|
||||
void encode(Node* node, char* code, int depth) {
|
||||
if (node->left == NULL && node->right == NULL) {
|
||||
code[depth] = '\0';//终止字符串
|
||||
printf("权重: %d, 编码: %s\n", node->weight, code);
|
||||
return;
|
||||
}
|
||||
code[depth] = '0';
|
||||
encode(node->left, code, depth + 1);
|
||||
code[depth] = '1';
|
||||
encode(node->right, code, depth + 1);
|
||||
}
|
||||
|
||||
// 解码函数
|
||||
void decode(Node* root, const char* encoded) {
|
||||
Node* current = root;
|
||||
while (*encoded) {
|
||||
if (*encoded == '0') {
|
||||
current = current->left;
|
||||
} else {
|
||||
current = current->right;
|
||||
}
|
||||
// 到达叶子节点,打印权重并返回根节点
|
||||
if (current->left == NULL && current->right == NULL) {
|
||||
printf("解码权重: %d\n", current->weight);
|
||||
current = root; // 回到根节点
|
||||
}
|
||||
encoded++;// 移动到下一个字符
|
||||
}
|
||||
}
|
||||
// 释放内存
|
||||
void freeTree(Node* node) {
|
||||
if (node) {
|
||||
freeTree(node->left);
|
||||
freeTree(node->right);
|
||||
free(node);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
int weights[] = {2, 3, 7, 9, 18, 25};
|
||||
int size = sizeof(weights) / sizeof(weights[0]);
|
||||
Node* root = createHuffmanTree(weights, size);
|
||||
char code[100]; // 假设编码长度不会超过100
|
||||
printf("编码:\n");
|
||||
encode(root, code, 0);
|
||||
|
||||
const char* encoded = "0010101111";
|
||||
printf("解码-0010101111:\n");
|
||||
decode(root, encoded);
|
||||
|
||||
freeTree(root);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,91 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
typedef struct Node
|
||||
{
|
||||
int weight;
|
||||
struct Node *lChild;
|
||||
struct Node *rChild;
|
||||
} Node;
|
||||
|
||||
// 比较函数,用于优先队列
|
||||
int compare(const void *a, const void *b)
|
||||
{
|
||||
return (*(Node **)a)->weight - (*(Node **)b)->weight;
|
||||
}
|
||||
|
||||
// 创建新的节点
|
||||
Node *createNode(int weight)
|
||||
{
|
||||
Node *newNode = (Node *)malloc(sizeof(Node));
|
||||
newNode->weight = weight;
|
||||
newNode->lChild = NULL;
|
||||
newNode->rChild = NULL;
|
||||
return newNode;
|
||||
}
|
||||
// 构建哈夫曼树
|
||||
Node *createHuffman(int *weights, int size)
|
||||
{
|
||||
Node **nodeArray = (Node **)malloc(size * sizeof(Node *));
|
||||
// 初始化节点数组
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
nodeArray[i] = createNode(weights[i]);
|
||||
printf("%d,", nodeArray[i]->weight);
|
||||
}
|
||||
qsort(nodeArray, size, sizeof(Node *), compare);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
printf("%d-", nodeArray[i]->weight);
|
||||
}
|
||||
// 使用qsort实现优先队列
|
||||
for (int i = size; i > 1; i--)
|
||||
{
|
||||
qsort(nodeArray, i, sizeof(Node *), compare);
|
||||
// 找到最右边两个节点
|
||||
Node *left = nodeArray[i - 1];
|
||||
Node *right = nodeArray[i - 2];
|
||||
// 创建新父节点
|
||||
Node *parent = createNode(left->weight + right->weight);
|
||||
parent->lChild = left;
|
||||
parent->rChild = right;
|
||||
// 将新节点放入数组中
|
||||
nodeArray[i - 2] = parent;
|
||||
}
|
||||
|
||||
Node *root = nodeArray[0];
|
||||
free(nodeArray);
|
||||
return root;
|
||||
}
|
||||
// 前序遍历输出
|
||||
void output(Node *head)
|
||||
{
|
||||
if (head == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
printf("%d\n", head->weight);
|
||||
output(head->lChild);
|
||||
output(head->rChild);
|
||||
}
|
||||
// 释放树的内存
|
||||
void freeTree(Node *root)
|
||||
{
|
||||
if (root == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
freeTree(root->lChild);
|
||||
freeTree(root->rChild);
|
||||
free(root);
|
||||
}
|
||||
int main()
|
||||
{
|
||||
int weights[] = {2, 18, 9, 3, 7,25};
|
||||
int size = sizeof(weights) / sizeof(weights[0]);
|
||||
Node *huffmanTree = createHuffman(weights, size);
|
||||
printf("前序遍历halftree:\n");
|
||||
output(huffmanTree);
|
||||
// 释放树的内存
|
||||
freeTree(huffmanTree);
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
f: 00
|
||||
n: 010
|
||||
m: 0110
|
||||
e: 0111
|
||||
h: 100
|
||||
: 1010
|
||||
a: 1011
|
||||
u: 1100
|
||||
o: 1101
|
||||
l: 111
|
||||
@@ -0,0 +1,51 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
typedef struct TreeNode {
|
||||
int val;
|
||||
struct TreeNode *left;
|
||||
struct TreeNode *right;
|
||||
} TreeNode;
|
||||
TreeNode* createNode(int value) {// 创建新节点
|
||||
TreeNode *newNode = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
newNode->val = value;
|
||||
newNode->left = NULL;
|
||||
newNode->right = NULL;
|
||||
return newNode;
|
||||
}
|
||||
void preorderTraversal(TreeNode *root) {
|
||||
if (root == NULL) return;
|
||||
printf("%d ", root->val); // 访问根节点
|
||||
preorderTraversal(root->left); // 遍历左子树
|
||||
preorderTraversal(root->right); // 遍历右子树
|
||||
}
|
||||
void inorderTraversal(TreeNode *root) {
|
||||
if (root == NULL) return;
|
||||
inorderTraversal(root->left); // 遍历左子树
|
||||
printf("%d ", root->val); // 访问根节点
|
||||
inorderTraversal(root->right); // 遍历右子树
|
||||
}
|
||||
void postorderTraversal(TreeNode *root) {
|
||||
if (root == NULL) return;
|
||||
postorderTraversal(root->left); // 遍历左子树
|
||||
postorderTraversal(root->right); // 遍历右子树
|
||||
printf("%d ", root->val); // 访问根节点
|
||||
}
|
||||
int main() {
|
||||
// 创建二叉树
|
||||
TreeNode *root = createNode(1);
|
||||
root->left = createNode(2);
|
||||
root->right = createNode(3);
|
||||
root->left->left = createNode(4);
|
||||
root->left->right = createNode(5);
|
||||
|
||||
printf("前序遍历: ");
|
||||
preorderTraversal(root);
|
||||
printf("\n");
|
||||
printf("中序遍历: ");
|
||||
inorderTraversal(root);
|
||||
printf("\n");
|
||||
printf("后序遍历: ");
|
||||
postorderTraversal(root);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user