今天对项目进行读入打乱编号的数据,最后会将一个有序的编号货物进行一次更新。然后修改了几个忽略的停顿点位,让界面的切换不至于那么唐突。
然后简单了解了哈夫曼树(最优二叉树):
哈夫曼树的建立是基于哈夫曼编码的原理。
即:为了使得某串二进制数据的编码后所占用的空间最小,应该将出现频率最高的数据编码长度最短,而出现频率低的数据编码长度较长,保证编码后的总体长度最短。
基本概念:
路径:从树中一个节点到另一个节点的分支构成这两个节点的路径
节点路径长度:两节点间路径上的分支数
树的路径长度:从树根到每一个节点的路径长度之和。记作:TL
例如:
完全二叉树的路径长度是最短的二叉树,但最短的二叉树不一定是完全二叉树。
权:将树中的节点赋给一个含有某种意义的值,则称这个树脂为节点的权。
节点的带权路径长度:从根节点到该节点之间的路径长度与该节点的权的乘积。
树的带权路径长度:树中所有叶子节点的带权的路径长度之和。
哈夫曼树的建立过程如下:
1.将所有数据按照出现频率从小到大排序;
2.选择出现频率最小的两个节点,合并成一个新的节点,频率等于两个子节点的频率之和;
3.将新节点插入到原来的节点集合中,重新排序;
4.重复步骤2和3,直到所有节点都被合并到一个根节点为止。
// 定义哈夫曼树结点
typedef struct huffman_node {
int weight; // 权重值
struct huffman_node *left, *right; // 左右子树指针
} HuffmanNode;
// 创建哈夫曼树结点
HuffmanNode* create_huffman_node(int weight) {
HuffmanNode *node = (HuffmanNode*)malloc(sizeof(HuffmanNode));
node->weight = weight;
node->left = NULL;
node->right = NULL;
return node;
}
// 构建哈夫曼树
HuffmanNode* build_huffman_tree(int *weights, int n) {
// 构建优先队列并插入所有叶子结点
PriorityQueue *pq = create_priority_queue(n);
for (int i = 0; i < n; i++) {
insert(pq, create_huffman_node(weights[i]), weights[i]);
}
// 按照权重逐个合并叶子结点,构建哈夫曼树
while (pq->size > 1) {
HuffmanNode *left = (HuffmanNode*)delete_min(pq);
HuffmanNode *right = (HuffmanNode*)delete_min(pq);
HuffmanNode *parent = create_huffman_node(left->weight + right->weight);
parent->left = left;
parent->right = right;
insert(pq, parent, parent->weight);
}
// 返回根节点
return (HuffmanNode*)delete_min(pq);
}
其中insert是优先队列(也叫堆)中的操作之一,用于向队列中插入一个元素。
具体实现中,通过创建优先队列并将所有叶子结点(即权重数组中的元素)插入队列,并按照权重逐个合并叶子结点,构建哈夫曼树。
目前对哈夫曼树的概念还比较模糊,还要加深学习。