Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从无到有构造序列哈夫曼树_C_Algorithm_Data Structures_Binary Tree_Huffman Code - Fatal编程技术网

C 从无到有构造序列哈夫曼树

C 从无到有构造序列哈夫曼树,c,algorithm,data-structures,binary-tree,huffman-code,C,Algorithm,Data Structures,Binary Tree,Huffman Code,给定一些文本文件,我需要读取每个字母数字字符并使用 读取字符、存储概率和创建节点以及使用指针创建Huffman的trie都得到了解决 但是,我需要使用二叉树的顺序表示来创建和初始化哈夫曼树,而不需要任何指针 这可以通过使用指针创建一个常规树,然后将其读入数组来实现,但我的目标是用节点直接填充数组 我考虑创建较小的树并将它们合并在一起,但选择了矩阵表示法,即从二进制堆中收集概率最小的元素,并将它们存储到矩阵行中,其中矩阵行表示节点在二叉树中的级别,以相反的顺序,也就是说 E.g. Given ch

给定一些文本文件,我需要读取每个字母数字字符并使用

读取字符、存储概率和创建节点以及使用指针创建Huffman的trie都得到了解决

但是,我需要使用二叉树的顺序表示来创建和初始化哈夫曼树,而不需要任何指针

这可以通过使用指针创建一个常规树,然后将其读入数组来实现,但我的目标是用节点直接填充数组

我考虑创建较小的树并将它们合并在一起,但选择了矩阵表示法,即从二进制堆中收集概率最小的元素,并将它们存储到矩阵行中,其中矩阵行表示节点在二叉树中的级别,以相反的顺序,也就是说

E.g. Given characters and their probabilities as char[int] pairs.

a[1], b[1], c[2], d[1], e[3], f[11], g[2]

I aim to create matrix that looks like 
____________________________________
    a   |    b   |    d   |    g   |
____________________________________
   ab   |    c   |   dg   |    e   |
____________________________________
   abc  |   deg  |        |        |
____________________________________ 
 abcdeg |    f   |        |        |  
____________________________________
abcdefg |        |        |        |
____________________________________

Where levels of a, b, c, d, e & f would be rows of a matrix.

目前,我一直在研究如何在元素的“父级”移动时递归地增加元素的级别(如果我将两个不同级别的节点['ab'和'c']组合起来,我很容易将c级别与ab级别相等并解决问题,但在这种情况下,例如'c'和'd'都位于第二行)以及如何创建完整的二叉树(如果它有左子节点,则需要有右子节点)仅包含终端节点的级别


事先,我知道这个问题不是很具体,如果有其他方法来解决这个问题,而不仅仅是解决上面提到的问题,我将不胜感激。

这是家庭作业的人为问题吗?我问这个问题是因为不使用链接的树的表示需要O(2^h)存储高度为h的树的空间。这是因为他们假设树是完整的,允许索引计算替换指针。因为对于大小为m的字母表,哈夫曼树的高度为h=m-1,所以最坏情况下数组的大小可能是巨大的。大部分都将被闲置

但是如果你放弃了链接必须是指针的想法,并允许它成为数组索引,那么你就没事了。很久以前,在动态内存分配器普及之前,这是标准的。这个问题对于这种方法特别好,因为你总是提前知道树中的节点数:比alp少一倍habet大小。在C中,您可以这样做

typedef结构{
char ch;
int f;
int left,right;//子项的索引。如果两者都为-1,则这是char ch的叶。
}节点;
#定义字母表大小7
节点节点[2*字母表大小-1]={
{'a',1,-1,-1},
{'b',1,-1,-1},
{'c',2,-1,-1},
{'d',1,-1,-1},
{'e',3,-1,-1},
{'f',11,-1,-1},
{'g',2,-1,-1},
//内部节点的数组的其余部分
};
int n_节点=字母表大小;
int add_internal_节点(int f,int left,int right){
//在数组中分配一个新节点并填写其值。
int i=n_节点++;
节点[i]=(节点){.f=f、.left=left、.right=right};
返回i;
}
现在您可以使用标准的树构建算法,如下所示:

int-build\u-huffman\u树(void){
//将叶节点的索引添加到优先级队列。
对于(int i=0;i1){
int a=remove_min_frequency();//从队列中删除最低频率节点的索引。
int b=移除最小频率();
int p=添加内部节点(节点[a].f+节点[b].f,a,b);
将_添加到_频率_优先级_队列(p);
}
//最后一个节点是哈夫曼树根。
返回删除最小频率();
}
解码算法将使用根的索引,如下所示:

char解码(位[],int-huffman\u树\u根\u索引){
int i=0,p=huffman树根索引;
while(节点[p]。左!=-1 | |节点[p]。右!=-1)//而不是叶
p=位[i++]?节点[p]。右:节点[p]。左;
返回节点[p].ch;
}

当然,这不会返回消耗了多少位,这是真正的解码器需要做的。真正的解码器也不会在数组中获取其位。最后,为了编码,除了子索引之外,还需要父索引。解决这些问题应该很有趣。祝你好运。

这是人为的家庭作业问题吗?我问bec因为不使用链接的树的表示需要O(2^h)存储高度为h的树的空间。这是因为他们假设树是完整的,允许索引计算替换指针。因为对于大小为m的字母表,哈夫曼树的高度为h=m-1,所以最坏情况下数组的大小可能是巨大的。大部分都将被闲置

但是如果你放弃了链接必须是指针的想法,并允许它成为数组索引,那么你就没事了。很久以前,在动态内存分配器普及之前,这是标准的。这个问题对于这种方法特别好,因为你总是提前知道树中的节点数:比alp少一倍habet大小。在C中,您可以这样做

typedef结构{
char ch;
int f;
int left,right;//子项的索引。如果两者都为-1,则这是char ch的叶。
}节点;
#定义字母表大小7
节点节点[2*字母表大小-1]={
{'a',1,-1,-1},
{'b',1,-1,-1},
{'c',2,-1,-1},
{'d',1,-1,-1},
{'e',3,-1,-1},
{'f',11,-1,-1},
{'g',2,-1,-1},
//内部节点的数组的其余部分
};
int n_节点=字母表大小;
int add_internal_节点(int f,int left,int right){
//在数组中分配一个新节点并填写其值。
int i=n_节点++;
节点[i]=(节点){.f=f、.left=left、.right=right};
返回i;
}
现在您可以使用标准的树构建算法,如下所示:

int-build\u-huffman\u树(void){
//将叶节点的索引添加到优先级队列。
对于(int i=0;i1){
int a=remove_min_frequency();//Remo