构建树

时间:2015-12-12 11:36:52

标签: c linked-list binary-tree huffman-code

我已经使用下面的代码构建了一个二叉树(huffman树),该代码按升序排序链接列表,但是当它完成运行时,它会打印位模式和应该在树中的一些节点AREN'吨。

代码本质上:

  1. 将父节点设置为指向两个最低节点

  2. 指定父节点的内部频率

  3. 将列表的开头指向现在位于节点2的位置(以避免重新使用节点)

  4. 将新的父节点插入树中的正确位置

  5. 获取树的长度

  6. 打印列表中剩下的所有节点

  7. 迭代直到剩下一个节点(这是根)。

  8. 任何有关其失败的原因的想法'沿途的节点?

    void build_tree(pqueue *list)
    {
    
        node *temp; 
        node* parent_node;
        int min_1, min_2, ind = 0, counter = 0, length = 2, head;
        int characters[CHARACTERS];
        temp = new_node();
    
        while (length > 1)
        {
            min_1 = 0;
            min_2 = 0;
            temp = list->start;           
            parent_node = new_node(); 
            parent_node->letter = '#';             
            min_1 = temp->frequency;
            parent_node->left = temp;         
            temp = temp->next;               
            min_2 = temp->frequency;
            parent_node->right = temp;       
            parent_node->frequency = min_1 + min_2;
            list->start = temp->next;
    
            while (ind == 0) /* inserting a node to the correct place */
            {
                if (temp != NULL && temp->next != NULL)
                {
                    temp = temp->next;
                    if (temp->frequency >= parent_node->frequency) /* in the middle */
                    {
                        parent_node->next = temp->next;
                        temp->next = parent_node;
                        ind = 1;
                    }
                    else if (temp->next == NULL) /* at the end */
                    {
                        temp->next = parent_node;
                        parent_node -> next = NULL;
                        ind = 1;
                    }
                }
            }
            ind = 0;
            temp =  list->start;
            while (temp->next != NULL) /* get number of nodes left to insert into tree */
            {
                temp = temp->next;
                counter++;
                printf("%c : %d\n", temp->letter, temp->frequency); 
            }
            printf("----------------------------------------------\n");
            length = counter;
            counter = 0;
        }
        printf("Found root with value of: %d\n", temp->frequency);
        head = 0;
        BitPatterns(temp, characters, head);
        temp = list->start;
        deallocate(temp, list);
    }
    
    
    void BitPatterns(node* root, int characters[], int head)
    {
        if (root->left)
        {
            characters[head] = 0;
            BitPatterns(root->left, characters, head +1);
        }
    
        if (root->right)
        {
            characters[head] = 1;
            BitPatterns(root->right, characters, head +1);
        }
    
    
        if (isLeaf(root))
        {
            printf("'%c' : ", root->letter);
            GetChars(characters, head);
    
        }
    }
    
    void GetChars(int characters[], int n)
    {
        int i, counter = 0;
        for (i = 0; i < n; ++i)
        {
            printf("%d", characters[i]);
            counter++;
    
        }
        printf(" (%d * \n", counter);
    
    }
    
    int isLeaf(node* root)
    {
        return !(root->left) && !(root->right) ;
    }
    

1 个答案:

答案 0 :(得分:2)

确定!这是一个艰难的调试。但是,我想我已经找到了问题所在。问题出在while循环中,您可以在其中找到列表的长度,然后留待处理。由于while循环中的条件为temp->next != NULL,因此,请考虑您的List大小为2,类似这样::

  

3 - &gt; 4 - &gt; NULL(数字代表某些节点的频率之和)

list->start指向3.并且您将此列表的长度测量为1而不是2,因为您正在检查temp->next != NULL

因此,您错过了列表的关键第二个节点,并且仅在第一个节点上运行BitPatterns(),并且您错过了几个节点。

一个可能的解决方案是在函数的开头插入一个while循环来测量一次的长度,并且可以在while的每个连续迭代中递减1循环,你组合两个节点,因为你要删除两个节点并总是将一个节点添加到列表,你只需要将length递减1.这也可以节省你做的大量额外的计算每次计算列表长度的列表末尾。

像这样的东西::

temp = list->start;
while(temp != NULL) {
    length++;
    temp = temp->next;
}

编辑:: 而且,我在你的代码::

中看到了另一个逻辑错误

考虑初始列表是这个::

  

1 - &gt; 2 - &gt; 4 - &gt; 5 - &gt; NULL

组合前两个节点,暂时将该节点称为A (with freq = 3)list_start指向4。因此,当您在列表中插入节点时,看起来像这样::

  

4 - &gt; A - &gt; 5 - &gt; NULL

虽然列表看起来像这样::

  

A - &gt; 4 - &gt; 5

这不会影响代码的运行,但可能会导致一些未优化的霍夫曼代码结果。