繁体   English   中英

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

[英]Binary Search Tree insertion not working

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

我的二叉树定义为:

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

我相信下面的更改将解决您的问题。

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

你的循环中既有设计缺陷又有彻头彻尾的bug。

设计缺陷:你正在分配一个新的节点,但是分配给cursor并不意味着你要分配给父节点的左或右子指针,它们首先让你到达那里。 您需要引用要填充的实际指针。 一种方法是使用指针指针,作为奖励,这将在开头消除is-my-root-null检查。

彻头彻尾的错误:你的左侧移动子句(即追逐左侧指针)可能会将cursor更改为NULL。 但追逐右侧的逻辑并不排除在其他条件下。 如果你的搜索在左侧跟随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++;
}

您没有指定任何现有节点指向新节点。 您遍历树,在结束时创建新节点,但不要将任何现有节点设置为指向新节点。

您可能希望将结构更改为:

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

与右手光标的逻辑相似。

暂无
暂无

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

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