簡體   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