简体   繁体   English

二叉树在构建树时丢失节点

[英]Binary tree is losing nodes while building the tree

I have built a binary tree (huffman tree) using the code below which takes a sorted in ascending order linked list, however when it finishes running it prints the bit-patterns and a few of the nodes that should be in the tree aren't. 我使用下面的代码构建了一个二叉树(霍夫曼树),该代码采用按升序排序的链表,但是当运行完成时,它会打印位模式,而树中的一些节点则不会。

The code essentially: 该代码本质上是:

  1. sets parent node to point at two lowest nodes 设置父节点指向两个最低节点

  2. assigns internal frequency of parent node 分配父节点的内部频率

  3. points the start of the list to now be at nodes 2 along from where it was (to avoid re-using nodes) 将列表的起点指向现在所在位置的节点2(以避免重复使用节点)

  4. inserts the new parent node into the correct position in the tree 将新的父节点插入树中的正确位置

  5. gets the length of the tree 获取树的长度

  6. print all nodes left in list 打印列表中剩余的所有节点

  7. iterates until one node is left (which is the root). 迭代直到剩下一个节点(它是根节点)。

Any ideas as to why its 'losing' nodes along the way? 关于为什么它的“丢失”节点一路上有什么想法?

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) ;
}

Ok! 好! It was a tough one to debug. 调试起来很困难。 But, I think I have found the problem. 但是,我想我已经找到问题了。 The problem is with the while loop, where you find the length of the list, that is left for processing. 问题在于while循环,您可以在其中找到要处理的列表长度。 Since the condition in the while loop is temp->next != NULL , so, consider that your List is of size 2, something like this :: 由于while循环中的条件是temp->next != NULL ,因此,请考虑您的List的大小为2,如下所示:::

3 --> 4 --> NULL (Numbers represent the sum of frequencies of some nodes) 3-> 4-> NULL(数字表示某些节点​​的频率之和)

With list->start pointing to 3. And you will measure the length of this list to 1 and not 2, because you are checking temp->next != NULL . 使用list->start指向3。您将测量此列表的长度为1而不是2,因为您正在检查temp->next != NULL

Because of this you miss a crucial second node of the list, and you run BitPatterns() only on the first node, and you miss a few nodes. 因此,您错过了列表中的关键第二个节点,并且仅在第一个节点上运行BitPatterns() ,并且错过了几个节点。

A possible solution to this would be to insert a while loop at the beginning of the function to measure the length for once, and that could be decremented by 1 in every consecutive iteration of the while loop, where you combine two nodes, since you are removing two nodes and adding one node to the list always, you only have to decrement the length by 1. This would also save a lot of extra computation that you do at the end of the list for computing the length of the list everytime. 一种可能的解决方案是在函数的开头插入一个while循环以测量一次长度,并且在while循环的每个连续迭代中可以将其递减1,因为您将两个节点合并在一起删除两个节点并始终向列表中添加一个节点,您只需将length减1。这也将节省您在列表末尾进行的每次计算列表长度的大量计算。

Something like this :: 像这样的东西::

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

EDIT :: Moreover, there's another logical bug that I see in your code :: 编辑::而且,在您的代码中还有一个逻辑错误::

Consider that the initial list is this :: 考虑初始列表是这个::

1 --> 2 --> 4 --> 5 --> NULL 1-> 2-> 4-> 5->空

You combine the first two nodes, let that node be called A (with freq = 3) for the moment and list_start points to 4 . 您将前两个节点组合起来,暂时将该节点称为A (with freq = 3) ,并且list_start指向4 So, when you insert the node in the list looks something like this :: 因此,当您在列表中插入节点时,看起来像这样:::

4 --> A --> 5 --> NULL 4-> A-> 5->空

Though the list, shall look something like this :: 虽然列表,看起来应该像这样::

A --> 4 --> 5 A-> 4-> 5

This, does not affect the functioning of the code, but might lead to some un-optimized huffman code results. 这不会影响代码的功能,但可能会导致某些未优化的霍夫曼代码结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM