C 指针算法:哈夫曼树遍历

C 指针算法:哈夫曼树遍历,c,pointers,tree,huffman-code,C,Pointers,Tree,Huffman Code,我对指针算法感到困惑,我想做一个树遍历函数,但我不太确定指针算法是否可以得到树中的远程节点。当在代码中看到它时,它会更加清晰,所以在这里 node **root = huffman_tree(probabilities); // I can only return that as a double ptr 现在,如果我想从根节点获取数据: printf("%lf", (*root)->data); 如果我想从根目录子目录中获取数据: printf("%lf", (*root)->

我对指针算法感到困惑,我想做一个树遍历函数,但我不太确定指针算法是否可以得到树中的远程节点。当在代码中看到它时,它会更加清晰,所以在这里

node **root = huffman_tree(probabilities); // I can only return that as a double ptr
现在,如果我想从根节点获取数据:

printf("%lf", (*root)->data);
如果我想从根目录子目录中获取数据:

printf("%lf", (*root)->left->data); // or (*root)->right->data
但如果我想进一步深入搜索,我不知道如何到达这些节点,该怎么办

printf("%lf", (*root)->left->left->data); // thats not working
此外,对于树遍历,这是不起作用的:程序崩溃

node **root = huffman_tree(probabailities);
preorder(*root);

void preorder(node *n){
if(n == NULL) return;
printf("%lf", n->data);
preorder(n->left);
preorder(n->right);
}

对于上述示例,程序崩溃

node **root = huffman_tree(probabailities);
preorder(*root);

void preorder(node *n){
if(n == NULL) return;
printf("%lf", n->data);
preorder(n->left);
preorder(n->right);
更新1:

看起来huffman_tree()确实返回了一个包含损坏节点的树,我一定是错误地为它们分配了内存

将概率数组传递给函数,然后获得如下步骤:

1) 创建具有给定概率的节点(n个概率-->n个新节点)[工作正常]

2) 查找概率最低的两个节点[工作正常] 3) 创建一个新节点,该节点是两个最低概率节点的父节点

4) 分配一个新的节点概率等于其子节点概率之和

5) 重复步骤2),直到只剩下一个无父节点

node **huffman_tree(double *probabs){


int num_of_nodes = NUM_OF_SYMBOLS;
int num = NUM_OF_SYMBOLS;

// 1) create nodes for given probabilities
node *leafs = (node*) malloc(num_of_nodes*sizeof(node));
int i;
for(i=0; i<num_of_nodes; i+=1){
    node *n = (node *) malloc(sizeof(node));
    n->probab = *(probabs + i);
    n->symbol = *(SYMBOLS + i);
    n->left = NULL;
    n->right = NULL;
    *(leafs+i) = *n;
    //free(n);
}

node **root;

while(num_of_nodes > 1){

    // 2) Find the two nodes with lowest probabilities
    node *two_mins =(node *)malloc(2*sizeof(node));
    two_mins = find_two_mins(leafs, num_of_nodes);
    node min_n1 = two_mins[0];
    node min_n2 = two_mins[1];


    // 3) Create a parent node with probability equals to sum of its children probabilities
            // add a parent node to leafs
    node *new_node = (node *) malloc(sizeof(node));
    new_node->probab = min_n1.probab + min_n2.probab;
    new_node->left = &min_n1;
    new_node->right = &min_n2;

    leafs = add_node(leafs, new_node, num);
    num += 1;
    leafs = remove_node(leafs, &min_n1, num);
    num -= 1;
    leafs = remove_node(leafs, &min_n2, num);
    num -= 1;

    num_of_nodes -= 1;

    root = &new_node;
}

return root;
函数remove_node()[似乎工作正常]

node *add_node(node *nodes, node *n, int num){
nodes = realloc(nodes, (num+1)*sizeof(node));
nodes[num] = *n;
return nodes;
node *remove_node(node *nodes, node *n, int num){
int i;
int index = 0;
for(i=0; i<num; i+=1){
    if(nodes_are_equal(nodes[i], *n)) index = i;
}

for(i=index; i<num-1; i+=1){
    nodes[i] = nodes[i+1];
}

nodes = realloc(nodes, (num-1)*sizeof(node));

return nodes;
下面是find_min()函数:

node *find_min(node *nodes, int num, node *min_node){

double min_probab = nodes[0].probab;
*min_node= nodes[0];

int i;
for(i=0; i<num; i+=1){
    if(nodes[i].probab< min_probab){
        min_probab = nodes[i].probab;
        *min_node = nodes[i];
    }
}

return min_node;
因为它输出“root=003A17F0”和“*root=00000000”

此外,我还提供了一个程序运行的屏幕截图,可以看到任意点的根值。

(*root)->left->left->data
是访问grand child节点的正确方法,前提是子节点不为null,并且假设您的节点类似于:

struct node
{
    double data;
    struct node * left;
    struct node * right;
}
没有看到完整的代码,很难确定这里发生了什么。您的空签入前序看起来不错,所以我怀疑您一定是在某种程度上破坏了一个节点,并在其中获取了一个无效(但非空)指针

将以下内容放在空签入前序之后,应该会使问题更加明显:

printf("processing node %p", n); fflush(stdout);
printf("  left=%p\n", n->left); fflush(stdout);
printf("  right=%p\n", n->right); fflush(stdout);
您正在寻找与其他指针“看起来”不一样的指针,尤其是在它崩溃之前

问题最可能的原因是哈夫曼树本身。我怀疑你有什么东西是从堆栈中获取一个节点的地址,而不是用malloc动态分配它

根据“答案”中提供的其他信息进行编辑:

您的问题可能出在
find_two_mins
函数中。下面的代码

node *two_mins =(node *)malloc(2*sizeof(node));
two_mins = find_two_mins(leafs, num_of_nodes);
node min_n1 = two_mins[0];
node min_n2 = two_mins[1];
是(正确地)为节点动态分配内存,但随后您将丢弃指向该动态内存的指针,并将其替换为
find\u two\u mins
的结果

我认为这个地方还存在其他一些内存泄漏(尽管这并没有引起您的问题)。在初始循环中

node *n = (node *) malloc(sizeof(node));
这不会被释放。您正在将该结构复制到正确分配的
leafs
数组中,因此只需将其设为
节点n


除此之外,我还没有详细研究过,因此可能会有更多问题,但请告诉我您的问题所在。

您需要使用
->
而不是
-
查看“这不起作用”是什么意思。它在干什么?你希望它做什么?你确定有一个节点吗?你能确认
huffman_tree
正在返回一个有效的指针吗?尝试放置
printf(“root=%p”,root)
printf(“*root=%p”,*root)紧跟在
哈夫曼树
呼叫之后。
node *n = (node *) malloc(sizeof(node));