2016-08-16 157 views
-1

所以我想学习如何在C中创建一个二叉树,到目前为止我已经得到了这个。C中的递归二叉树插入

void addRecordsToTree(struct date *in, struct date *root) { 
    if (root == NULL) { 
     root = malloc(sizeof(struct date)); 
     root = in; 
     return; 
    } else { 
     //Right side of tree processing 
     if (compareTwoRecords(in, root) >= 0) { 
      addRecordsToTree(in, root->right); 
      return; 
     } else { 
      root->right = in; 
      return; 
     } 
     //Left side of tree processing. 
     if (compareTwoRecords(in, root) < 0) { 
      addRecordsToTree(in, root->left); 
      return; 
     } else { 
      root->left = in; 
      return; 
     } 
    } 
} 

int main() { 
    loadFiles(); 
    struct date treeRoot; 
    struct date *old = malloc(sizeof(struct date)); 
    old = loadContentsIntoHeap(files[file2014]); 

    addRecordsToTree(&old[0], &treeRoot); 
    addRecordsToTree(&old[1], &treeRoot); 
    addRecordsToTree(&old[2], &treeRoot); 
    addRecordsToTree(&old[3], &treeRoot); 
    addRecordsToTree(&old[4], &treeRoot); 
    addRecordsToTree(&old[5], &treeRoot); 

    printRecord(7, old); 

    return 0; 
} 

问题是当我在调试器中检查程序的状态时,只是混乱了数据。我认为这可能是一个类型问题,我发现指针是一个令人难以置信的概念。我不确定我是否已经正确使用它们。所以这里是调试器的屏幕截图。

debugger shot of last addRecordsToTree() call

正如你可以在底部看到结构称为“老”是我试图让树出来的树根和在这里我想将它,但我不明白为什么数据我得到这些垃圾值。

什么是与左右的内存地址?我没有正确创建它们吗?

我做的另一个观察是,当我在调试器中观察我的代码时,似乎root永远不是== NULL并且永远不会被设置,为什么?

+4

'root = malloc(sizeof(struct date)); root = in;' - 所以你正在分配内存,然后通过重新分配相同的指针来泄漏它。 –

+0

那部分永远不会运行。 – Definity

+0

无论如何,你的代码粘贴缺少*关键*部分。像分配和初始化一样。 –

回答

0

我看到你的“addRecordsToTree” - 函数另外一个问题:

“树处理//右侧”的IF-块

将百达从函数返回。无论“IF” - 表达是真还是假。 所以你的树的左叶永远不会被插入。所以你probalby应该检查/调试该功能。

+0

是的,这是我的意图,因为它自称它永远不会到达返回,因为递归调用是阻碍的,​​它只是一旦到达插入点,它将从堆栈帧返回,然后返回。其他只是一个任务,一旦分配它可以返回。这是我的noob逻辑无论如何 – Definity

1

你只是做了以下内容:

int x = 2; 
int y = x; 
y = 5; 

是这里的第二行必要的或第三个。如果你这样做,这是完全不合逻辑的程序。你只是用指针而不是整数来做同样的事情。你首先有一个指向动态内存基址的指针,然后你通过第二次初始化它来覆盖它。

而且,迭代方法比递归方法好得多。我共享代码以递归和迭代方式在二叉树中插入节点:

void insert(struct node *temp, struct node **root) 
{ 
    while (*root != NULL) 
     root = (*root)->element < temp->element ? &(*root)->left : &(*root)->right; 
    *root = temp; 
} 

#if 0 
/* Recursive approach */ 
void insert(struct node *temp, struct node **root) 
{ 
    if(*root == NULL) 
     *root = temp; 
    else if ((*root)->element < temp->element) 
     insert(temp, &(*root)->left); 
    else 
     insert(temp, &(*root)->right); 
} 
#endif 

void create_node(int x, struct node **root) 
{ 
    struct node *temp = (struct node *) malloc(sizeof(struct node)); 

    if (temp == NULL) 
     printf("Unable to allocate memory. Free some space.\n"); 
    else 
    { 
     temp->left = NULL; 
     temp->right = NULL; 
     temp->element = x; 
     insert(temp, root); 
    } 
} 

int main() 
{ 
    struct node *root = NULL; 
    create_node(1, &root); 
    create_node(2, &root); 
    create_node(3, &root); 
    return 0; 
} 
+1

迭代为什么比递归好得多?我发现它更容易阅读,并且可能具有相同的性能。 – anatolyg

+0

关于递归只是一件事:堆栈溢出。那是一个不同的话题。 –

+0

只有在迭代方法太差或比递归更长时才应用它。如果两个选项具有相同的时间复杂度,那么您应该始终遵循迭代的方法。我可能没有在修改链接对象时使用所谓的“双指针”用法。一般来说,理解更为困难,但是更为一般的方法。 https://www.youtube.com/watch?v=GiAhUYCUDVc –