如何在C中将节点添加到二叉树?

时间:2017-11-28 21:52:01

标签: c binary-tree nodes ansi-c

如果A(左)和B(右)已满,如何向二叉树中添加更多节点?我只需要创建一个平衡的树。但我无法弄清楚如何向树中添加更多数据。任何帮助将不胜感激。

提前感谢任何tipps。

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

struct node
{
    char *titel;
    struct node *A;
    struct node *B;
};

void display(struct node *leaf)
{
    if (leaf != NULL)
    {
        display(leaf->A);
        printf("%s\n",leaf->titel);
       display(leaf->B);
    }
}

struct node *insert(char* titel, struct node **leaf)
{
    if (*leaf == 0)
    {
        *leaf = (struct node*)malloc(sizeof(struct node));
        (*leaf)->titel = malloc(strlen(titel)+1);
        strcpy((*leaf)->titel,titel);
        (*leaf)->A = NULL;
        (*leaf)->B = NULL;
    }
    else if ((*leaf)->A == NULL)
    {
        (*leaf)->A = insert(titel,&(*leaf)->A);
    }
    else if ((*leaf)->B == NULL )
    {
        (*leaf)->B = insert(titel,&(*leaf)->B);
    }
    //WHAT TO ADD HERE TO CREATE ANOTHER NODE?
    return(*leaf);
}

int main(int argc, char const *argv[])
{
    struct node *root = NULL;
    insert("root",&root);
    insert("chapter_1A",&root);
    insert("chapter_1B",&root);
    insert("chapter_2A",&root);
    insert("chapter_2B",&root);
    insert("chapter_3A",&root);
    display(root);
    return 0;
}

输出应该像平衡的二叉树。不能打印,但要像存储器一样存储。

实际输出:

chapter_1A
root
chapter_1B
                     root
                  /       \
            chapter_1A  chapter_1B
           /      \      /      \
         ch_2A  ch_2B  ch_3A   ch_3B
              and so on.

1 个答案:

答案 0 :(得分:3)

  

如果A(左)和B(右)已经满了,如何向二叉树中添加更多节点?

通过“完整”,我认为你的意思是两个子节点本身都有两个孩子。在这种情况下,必须将任何新节点添加到子节点之一。通常,您可以通过递归函数执行此操作,以便在子项的子项也“满”时正确处理该情况,等等。

  

我只需要创建一个平衡的树

(注意“平衡”本身就意味着几件事。例如,有“高度平衡”和“重量平衡”树。你没有指定你想要的东西。

那么问题是哪个(完整)孩子要添加一个新节点 - 右边还是左边?一种选择是保持每个节点的总后代的计数,并始终添加到具有最少的子节点。

另一种选择是保持树中节点总数的计数,并使用该数字中的位(忽略第一个1位)来决定插入新节点的位置。例如,如果您有一个包含5个节点的树:

                 A
           B            C
         D   E

要添加新节点,请将节点计数增加到6,即二进制的110。忽略第一个1;将下一个1解释为“向右”(将您带到C),将以下0解释为“向左走”(它会告诉您插入{{的左子) 1}})。你的代码就像这样:

C

注意我将返回类型更改为void insert(char* titel, struct node **leaf, int nodeCount, int bitPos) { if (*leaf == 0) { *leaf = (struct node*)malloc(sizeof(struct node)); (*leaf)->titel = malloc(strlen(titel)+1); strcpy((*leaf)->titel,titel); (*leaf)->A = NULL; (*leaf)->B = NULL; } else { int currentBit = (nodeCount >> bitPos) & 1; if (currentBit == 0) { // insert to left insert(titel, &((*leaf)->A), nodeCount, bitPos - 1); } else { // insert to right insert(titel, &((*leaf)->B), nodeCount, bitPos - 1); } } } ,因为您不需要返回值。我将初始void值的计算作为练习(请记住:它是最高位bitPos位的位置,减去1)。

如果您还需要从树中删除元素,则需要找到一种方法来重新平衡它。

请注意,有几种数据结构和算法可用于维护支持插入和删除的平衡树。例如,请参阅red-black treesAVL trees。这些通常用于有序树,但是对于无序但平衡的树来说它们应该是微不足道的。