c++布尔值在2-3树搜索中总是错误地返回true

C++ Boolean Value always incorrectly returns true in 2-3 Tree Search

本文关键字:错误 返回 true 布尔值 搜索 c++      更新时间:2023-10-16

伙计们,我简直要把头发都扯掉了。问题来了。我已经硬编码了一个2-3树,并验证了它与使用无序遍历函数一起工作,该函数输出当前所在节点的值。所以我知道树是正确建造的。

 Node *r;
  Node zero,one,two,three,four,five,six,seven,eight,nine,ten;
  r = &zero;
          //Root
 zero.small = 50;
 zero.large = 90;
 zero.left = &one;       //Child node to the left
 zero.middle = &four;    //Child node in the middle
 zero.right = &seven;    //Child node to the right
  //Left Tree
 one.small = 20;
 one.large = NULL;
 one.left = &two;
 one.middle = NULL;
 one.right = &three;
 two.small = 10;
 two.large = NULL;
 two.left = NULL;
 two.middle = NULL;
 two.right = NULL;
 three.small = 30;
 three.large = 40;
 three.left = NULL;
 three.middle = NULL;
 three.right = NULL;
  //Middle Tree
 four.small = 70;
 four.large = NULL;
 four.left = &five;
 four.middle = NULL;
 four.right = &six;
 five.small = 60;
 five.large = NULL;
 five.left = NULL;
 five.middle = NULL;
 five.right = NULL;
 six.small = 80;
 six.large = NULL;
 six.left = NULL;
 six.middle = NULL;
 six.right = NULL;
  //Right Tree
 seven.small = 120;
 seven.large = 150;
 seven.left = &eight;
 seven.middle = &nine;
 seven.right = &ten;
 eight.small = 100;
 eight.large = 110;
 eight.left = NULL;
 eight.middle = NULL;
 eight.right = NULL;
 nine.small = 130;
 nine.large = 140;
 nine.left = NULL;
 nine.middle = NULL;
 nine.right = NULL;
 ten.small = 160;
 ten.large = NULL;
 ten.left = NULL;
 ten.middle = NULL;
 ten.right = NULL;
 cout<<"inorder traversal for debug"<<endl;
 inOrder(*r);

输出将为:10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160

这就证明了树是正确构建的。我被要求修改代码来搜索树中的值。所以我写了下面这个函数,它本质上是一个无序遍历函数减去输出和一个简单的if语句,如果在树中找到了搜索键,它会返回TRUE。

bool retrieve(Node r, int key)
{
 if (r.left)
    retrieve(*r.left, key);
 if (r.small)
 {
     if (r.small == key)
    {
        cout<<"The node: "<<r.small<<" is equal to search key: "<<key<<endl; //for debug purposes
        return true;
    }
 }
 if (r.middle)
    retrieve(*r.middle, key);
 if (r.large)
 if (r.right)
    retrieve(*r.right, key);  
}

提示用户输入要搜索的数字(int key),在输入时输入if语句

if (retrieve(*r, key))
 {
     cout<<key<<" is found!"<<endl;
 }
 else
     cout<<key<<" is not found!"<<endl;

现在的问题是,这在逻辑上对我来说似乎是合理的,但是当我输入值"85"(它根本不在树上)时,程序输出"85是找到的!"。请注意,它没有输出函数中的COUT语句。 cout<<"The node: "<<r.small<<" is equal to search key: "<<key<<endl;我已经调试并逐步通过程序,无论bool函数(检索)总是返回true…怎么啦?因此,在输入"60"(位于树中)时,我将bool函数中的if语句切换为返回false(仅用于调试目的),布尔函数仍然返回true。我尝试了几种略有不同的代码组合,但无济于事。到底发生了什么?

提前感谢,

泰勒

永远不返回值,除非在if (r.small == key)分支中。

从2-3树-维基百科,我想说你的代码应该比较keysmalllarge键首先,根据比较返回retrieve(*r.left/middle/right, key)的结果。

以下内容(未经测试)

if (key < r.small)
    return retrieve(*r.small, key);
if (key == r.small)
    return TRUE;
if (r.right == NULL)
    return retrieve(*r.middle, key);
if (key < r.large)
    return retrieve(*r.middle, key);
if (key == r.large)
    return TRUE;
return retrieve(*r.right, key);

首先需要检查在当前节点中找到的键是小键还是大键,如果是,则返回true。如果不是,则需要在每个包含的节点上递归地调用retrieve,如果其中任何一个节点返回true,则返回true。如果你的函数还没有返回,你需要返回false

您需要进行初始测试,以查看递归是否应该因为您处于最小节点而停止。

// precondition: current is not 0
// returns: true or false. If true, location is set to the node 
// where it was found.
bool DoSearch(Node *current, int key, Node *location)
{
 /*
  * Is key in current?
  */
if (current->smallValue == key || (current->isThreeNode() 
       && current->largeValue == key)) {
    location = current;
    return true;
} else if ((current->isLeafNode())) {
    location = current;
    return false;
 /*
  *  Does current have two keys?
  */
} else if (current->isThreeNode()){
    if (key < current->smallValue) {
        DoSearch(key, current->leftChild, location);
    }  else if (key < current->largeValue) {
        DoSearch(key, current->middleChild, location);
    } else {
        DoSearch(key, current->rightChild, location);
    }
} else { // ...or only one?
     if (key < current->smallValue) {
        DoSearch(key, current->leftChild, location);
    }  else {
        DoSearch(key, current->rightChild, location);
    }
}
}