简体   繁体   English

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

[英]Binary Search Tree insertion not working

I've been playing about with this Binary search tree for a while but I can't seem to insert or change any of the tree properties. 我一直在玩这个二进制搜索树一段时间,但我似乎无法插入或更改任何树属性。

My binary tree is defined as: 我的二叉树定义为:

struct tree{
    Node * root;
    int size;
};
struct node{
    int value;
    Node * left;
    Node * right;
};

Therefore my binary tree is composed of nodes. 因此我的二叉树由节点组成。 Now the bit that doesn't work: 现在这一点不起作用:

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

Can someone tell me where I'm going wrong? 谁能告诉我哪里出错了? I expected calls to add() would increase the size member as well as creating new nodes but I can't seem to get it. 我期望调用add()会增加size成员以及创建新节点,但我似乎无法得到它。

I believe the changes below will fix your problem. 我相信下面的更改将解决您的问题。

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

You're have both a design flaw and an outright-bug in your loop. 你的循环中既有设计缺陷又有彻头彻尾的bug。

The design flaw: You're allocating a new node, but assigning to cursor doesn't mean you're assigning to the parent node left or right child pointer that got you there in the first place. 设计缺陷:你正在分配一个新的节点,但是分配给cursor并不意味着你要分配给父节点的左或右子指针,它们首先让你到达那里。 You need a reference to the actual pointer you're going to populate. 您需要引用要填充的实际指针。 One way to do this is with a pointer-to-pointer, and as a bonus, this eliminates the is-my-root-null check at the beginning. 一种方法是使用指针指针,作为奖励,这将在开头消除is-my-root-null检查。

The outright bug: Your left-side movement clause (ie chasing a left-side pointer) will potentially change cursor to NULL. 彻头彻尾的错误:你的左侧移动子句(即追逐左侧指针)可能会将cursor更改为NULL。 but the logic for chasing the right side is not excluded with an else if condition. 但追逐右侧的逻辑并不排除在其他条件下。 If your search followed a left-side to null it would fault chasing the right side of a null pointer. 如果你的搜索在左侧跟随null,那么它将错误地追逐空指针的右侧。 This was obviously a problem. 这显然是一个问题。

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++;
}

I should also note that you can skip the equality check by assuming a strict-weak order. 我还应该注意,你可以通过假设一个严格弱的顺序来跳过相等性检查。 Ie the following rule can be considered valid: 即以下规则可被视为有效:

if (!(a < b) && !(b < a)) then a == b is true.

That makes your insertion simpler as well. 这也使您的插入更简单。

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++;
}

You're not assigning any of your existing nodes to point to the new node. 您没有指定任何现有节点指向新节点。 You walk through the tree, create a new node when you get to the end, but you don't set any existing nodes to point to the new node. 您遍历树,在结束时创建新节点,但不要将任何现有节点设置为指向新节点。

You might want to change your structure to something like: 您可能希望将结构更改为:

if ( value < cusor->value )
{
  if ( cursor->left )
  {
    cursor = cursor->left;
  }
  else
  {
    cursor->left = newNode(value);
    break;
  }
}

with similar logic for the right-hand cursor. 与右手光标的逻辑相似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM