-
Notifications
You must be signed in to change notification settings - Fork 0
/
huffman.c
173 lines (150 loc) · 3.39 KB
/
huffman.c
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/**
* Huffman树(C语言): C语言实现的Huffman树。
*
* 构造Huffman树时,使用到了最小堆。
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "huffman.h"
// 创建最小堆
extern void create_minheap(Type a[], int size);
// 新建一个节点,并将最小堆中最小节点的数据复制给该节点。
extern HuffmanNode* dump_from_minheap();
// 将data插入到二叉堆中。0表示成功,-1表示失败。
extern int dump_to_minheap(HuffmanNode *node);
// 销毁最小堆
extern void destroy_minheap();
/*
* 前序遍历"Huffman树"
*/
void preorder_huffman(HuffmanTree tree)
{
if(tree != NULL)
{
printf("%d ", tree->key);
preorder_huffman(tree->left);
preorder_huffman(tree->right);
}
}
/*
* 中序遍历"Huffman树"
*/
void inorder_huffman(HuffmanTree tree)
{
if(tree != NULL)
{
inorder_huffman(tree->left);
printf("%d ", tree->key);
inorder_huffman(tree->right);
}
}
/*
* 后序遍历"Huffman树"
*/
void postorder_huffman(HuffmanTree tree)
{
if(tree != NULL)
{
postorder_huffman(tree->left);
postorder_huffman(tree->right);
printf("%d ", tree->key);
}
}
/*
* 创建Huffman树结点。
*
* 参数说明:
* key 是键值。
* left 是左孩子。
* right 是右孩子。
* parent 是父节点
*/
HuffmanNode* huffman_create_node(Type key, HuffmanNode *left, HuffmanNode* right, HuffmanNode* parent)
{
HuffmanNode* p;
if ((p = (HuffmanNode *)malloc(sizeof(HuffmanNode))) == NULL)
return NULL;
p->key = key;
p->left = left;
p->right = right;
p->parent = parent;
return p;
}
/*
* 创建Huffman树
*
* 参数说明:
* a 权值数组
* size 数组大小
*
* 返回值:
* Huffman树的根
*/
HuffmanNode* create_huffman(Type a[], int size)
{
int i;
HuffmanNode *left, *right, *parent;
// 建立数组a对应的最小堆
create_minheap(a, size);
for(i=0; i<size-1; i++)
{
left = dump_from_minheap(); // 最小节点是左孩子
right = dump_from_minheap(); // 其次才是右孩子
// 新建parent节点,左右孩子分别是left/right;
// parent的大小是左右孩子之和
parent = huffman_create_node(left->key+right->key, left, right, NULL);
left->parent = parent;
right->parent = parent;
// 将parent节点数据拷贝到"最小堆"中
if (dump_to_minheap(parent)!=0)
{
printf("插入失败!\n结束程序\n");
destroy_huffman(parent);
parent = NULL;
break;
}
}
// 销毁最小堆
destroy_minheap();
return parent;
}
/*
* 销毁Huffman树
*/
void destroy_huffman(HuffmanTree tree)
{
if (tree==NULL)
return ;
if (tree->left != NULL)
destroy_huffman(tree->left);
if (tree->right != NULL)
destroy_huffman(tree->right);
free(tree);
}
/*
* 打印"Huffman树"
*
* tree -- Huffman树的节点
* key -- 节点的键值
* direction -- 0,表示该节点是根节点;
* -1,表示该节点是它的父结点的左孩子;
* 1,表示该节点是它的父结点的右孩子。
*/
void huffman_print(HuffmanTree tree, Type key, int direction)
{
if(tree != NULL)
{
if(direction==0) // tree是根节点
printf("%2d is root\n", tree->key, key);
else // tree是分支节点
printf("%2d is %2d's %6s child\n", tree->key, key, direction==1?"right" : "left");
huffman_print(tree->left, tree->key, -1);
huffman_print(tree->right,tree->key, 1);
}
}
void print_huffman(HuffmanTree tree)
{
if (tree!=NULL)
huffman_print(tree, tree->key, 0);
}