二进制搜索树插入不起作用

时间:2013-10-25 17:06:38

标签: c pointers binary-search-tree

我一直在玩这个二进制搜索树一段时间,但我似乎无法插入或更改任何树属性。

我的二叉树定义为:

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成员以及创建新节点,但我似乎无法得到它。

3 个答案:

答案 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;
  }
}

具有类似右手光标的逻辑。