我一直在玩这个二进制搜索树一段时间,但我似乎无法插入或更改任何树属性。
我的二叉树定义为:
struct tree{
Node * root;
int size;
};
struct node{
int value;
Node * left;
Node * right;
};
因此我的二叉树由节点组成。现在这一点不起作用:
void add(int value, Tree *t){
//1. if root is null create root
if(t->root == NULL){
t->root = nodeCreate(value);
t->size ++;
return;
}
Node * cursor = t->root;
while(cursor != NULL){
if(value == cursor->value){
printf("value already present in BST\n");
return;
}
if(value < cursor->value){
cursor = cursor->left;
}
if(value > cursor->value){
cursor = cursor->right;
}
}
//value not found in BST so create a new node.
cursor = nodeCreate(value);
t->size = t->size + 1;
}
有人能告诉我哪里出错了吗?我希望调用add()
会增加size成员以及创建新节点,但我似乎无法得到它。
答案 0 :(得分:1)
我相信以下更改将解决您的问题。
void add(int value, Tree *t){
if(t->root == NULL){
t->root = nodeCreate(value);
t->size ++;
return;
}
Node * cursor = t->root;
Node * last = null;
while(cursor != NULL){
last = cursor;
if(value == cursor->value){
printf("value already present in BST\n");
return;
}
if(value < cursor->value){
cursor = cursor->left;
}
if(value > cursor->value){
cursor = cursor->right;
}
}
//value not found in BST so create a new node.
cursor = nodeCreate(value);
if (value > cursor->value)
{
last->right = cursor;
}
else
{
last->left = cursor;
}
t->size = t->size + 1;
}
答案 1 :(得分:1)
你的循环中既有设计缺陷又有彻头彻尾的bug。
设计缺陷:您正在分配一个新节点,但是分配给cursor
并不意味着您将首先分配给父节点的左或右子指针。您需要引用要填充的实际指针。一种方法是使用指针指针,作为奖励,这将在开头消除is-my-root-null检查。
彻头彻尾的错误:你的左侧移动子句(即追逐左侧指针)可能会将cursor
更改为NULL。但是, else if 条件不会排除追逐右侧的逻辑。如果你的搜索在左侧跟随null,那么它将错误地追逐空指针的右侧。这显然是一个问题。
void add(int value, Tree *t)
{
Node **pp = &(t->root);
while (*pp)
{
if(value == (*pp)->value) {
printf("value already present in BST\n");
return;
}
if(value < (*pp)->value)
pp = &(*pp)->left;
else if(value > (*pp)->value)
pp = &(*pp)->right;
}
*pp = nodeCreate(value);
t->size++;
}
我还应该注意,您可以通过假设严格弱的顺序跳过相等性检查。即以下规则可视为有效:
if (!(a < b) && !(b < a)) then a == b is true.
这也使您的插入更简单。
void add(int value, Tree *t)
{
Node **pp = &(t->root);
while (*pp)
{
if (value < (*pp)->value)
pp = &(*pp)->left;
else if ((*pp)->value < value)
pp = &(*pp)->right;
else { // must be equal.
printf("value already present in BST\n");
return;
}
}
*pp = nodeCreate(value);
t->size++;
}
答案 2 :(得分:0)
您没有指定任何现有节点指向新节点。您遍历树,在结束时创建新节点,但不要将任何现有节点设置为指向新节点。
您可能希望将结构更改为:
if ( value < cusor->value )
{
if ( cursor->left )
{
cursor = cursor->left;
}
else
{
cursor->left = newNode(value);
break;
}
}
具有类似右手光标的逻辑。