簡體   English   中英

二叉樹在構建樹時丟失節點

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

我使用下面的代碼構建了一個二叉樹(霍夫曼樹),該代碼采用按升序排序的鏈表,但是當運行完成時,它會打印位模式,而樹中的一些節點則不會。

該代碼本質上是:

  1. 設置父節點指向兩個最低節點

  2. 分配父節點的內部頻率

  3. 將列表的起點指向現在所在位置的節點2(以避免重復使用節點)

  4. 將新的父節點插入樹中的正確位置

  5. 獲取樹的長度

  6. 打印列表中剩余的所有節點

  7. 迭代直到剩下一個節點(它是根節點)。

關於為什么它的“丟失”節點一路上有什么想法?

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

好! 調試起來很困難。 但是,我想我已經找到問題了。 問題在於while循環,您可以在其中找到要處理的列表長度。 由於while循環中的條件是temp->next != NULL ,因此,請考慮您的List的大小為2,如下所示:::

3-> 4-> 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-> 2-> 4-> 5->空

您將前兩個節點組合起來,暫時將該節點稱為A (with freq = 3) ,並且list_start指向4 因此,當您在列表中插入節點時,看起來像這樣:::

4-> A-> 5->空

雖然列表,看起來應該像這樣::

A-> 4-> 5

這不會影響代碼的功能,但可能會導致某些未優化的霍夫曼代碼結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM