使用C.编写我的第一个简单树数据结构。Preorder遍历不打印任何值,只打印null。无法检测到问题所在。感谢
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node* left;
struct node* right;
} Node;
新节点创建
Node* newNode(int key) {
Node* new = (Node*)malloc(sizeof(struct node));
new->data = key;
new->left = NULL;
new->right = NULL;
return new;
}
使用递归插入
Node* insert(Node* node, int key) {
if (node == NULL)
return newNode(key);
else if (node->data > key)
node->left = insert(node->left, key);
else if (node->data < key)
node->right = insert(node->right, key);
else
return (node);
}
未获得预期的输出
void preorder(Node* node) {
if (node != NULL) {
printf("%d ",node->data);
preorder(node->left);
preorder(node->right);
}
}
int main() {
//Thinking issue might be in below initialization.
Node* root=NULL;
root = insert(root,10);
root = insert(root,20);
root = insert(root,30);
root = insert(root,40);
root = insert(root,50);
root = insert(root,60);
root = insert(root,25);
preorder(root);
return 0;
}
答案 0 :(得分:2)
您忘了在新节点中添加键值;)
只需将new->data = key;
添加到newNode代码
Node* newNode(int key)
{
Node* new = (Node*)malloc(sizeof(struct node));
new->data = key;
new->left = NULL;
new->right = NULL;
return new;
}
目前,由于node->data
未定义else if (node->data > key)
,else if (node->data < key)
将具有未定义的行为。
编辑:顺便说一下,当你进入2 else if
条件时,要小心,你永远不会返回一个节点,然后root = insert(root,20);
将无效。 需要在这种情况下返回值。
Node* insert(Node* node, int key)
{
if (node==NULL)
return newNode(key);
else if (node->data > key)
node->left = insert(node->left, key);
else if (node->data < key)
node->right = insert(node->right, key);
return node;
}
此代码应该有效(如果你也改变了newNode函数)
答案 1 :(得分:2)
插入功能中有几个错误。它不会在每个分支上返回有效指针,因此如果将结果分配给它,则不能将root
声明为指向有效地址。始终将编译器警告转换为尽可能高的级别。
即使不平衡的BST是递归数据结构,我建议你抵制递归实现其操作的冲动。编写起来可能很简单,但并不总是很容易调试。
Node* insert(Node* root, int key)
{
Node **link= &root;
while(*link) {
if((*link)->data > key) {
link = &((*link)->left);
} else {
link = &((*link)->right);
}
}
*link = newNode(key);
return root;
}
花点时间欣赏这里的抽象。上面的代码实现了间接以找到添加点。它始终跟踪必须在添加时修改的树链接。一旦找到空链接(*link == NULL
),我们就可以分配给它。
它还修复了代码中的另一个无声错误,重复键的添加也会覆盖根。我冒昧地将它们添加到正确的子树中,这在某些实现中是常见的。但是你可以在那里停下来并立即返回root
。