简体   繁体   English

C++ 二叉搜索树和指针

[英]C++ Binary Search Tree and Pointers

could you please tell me why the call of the method binaryTree.Exists(5);你能告诉我为什么调用binaryTree.Exists(5);方法binaryTree.Exists(5); says that "5 doesn't exist in the binary tree"?说“二叉树中不存在 5”? when debugging, it's like when trying to access the node where 5 is inserted doesn't exist anymore.调试时,就像尝试访问已插入 5 的节点不再存在一样。 i don't see why.我不明白为什么。 thank you!!!谢谢你!!!

#include <iostream>

using namespace std;


class Node
{
    private:
        int _value;
        Node* left;
        Node* right;

    public:
        Node(int value):_value(value), left(NULL), right(NULL)
        {
        }
        Node* returnLeftChild()
        {
            return left;
        }
        Node* returnRightChild()
        {
            return right;
        }
        void setLeftChild(Node* l)
        {
            left=l;
        }
        void setRightChild(Node* r)
        {
            right=r;
        }
        int getValue()
        {
            return _value;
        }
};

class BinaryTree
{
    private:
        Node parent;
        void AddToOneTree(Node* parent, int value)
        {
            if (value==parent->getValue())
            {
                return;
            }
            if (value>parent->getValue())
            {
                if (parent->returnRightChild()==NULL)
                {
                    Node newNode(value);
                    parent->setRightChild(&newNode);
                    return;
                }
                else
                {
                    AddToOneTree(parent->returnRightChild(), value);
                }
            }
            if (value<parent->getValue())
            {
                if (parent->returnLeftChild()==NULL)
                {
                    Node newNode(value);
                    parent->setLeftChild(&newNode);
                    return;
                }
                else
                {
                    AddToOneTree(parent->returnLeftChild(), value);
                }
            }           
        }

        void LookForValue(Node* parent, int value, bool found)
        {
            if (value>parent->getValue())
            {
                if (parent->returnRightChild()!=NULL)
                {
                    if (parent->returnRightChild()->getValue()==value)
                    {
                        found= true;
                        goto HERE;
                    }
                    else
                    {
                        LookForValue(parent->returnRightChild(), value, found);
                    }
                }
            }
            else if (value<parent->getValue())
            {
                if (parent->returnLeftChild()!=NULL)
                {
                    if (parent->returnLeftChild()->getValue()==value)
                    {
                        found= true;
                        goto HERE;
                    }
                    else
                    {
                        LookForValue(parent->returnLeftChild(), value, found);
                    }
                }
            }
            HERE:;
        }

    public:
        BinaryTree(int parentValue):parent(parentValue)
        {   
        }

        void Add(int value)
        {
            AddToOneTree(&parent, value);
        }

        void Exists(int value)
        {
            bool found = false;
            if (parent.getValue()==value)
            {
                cout << value << " exists in the Binary Tree." << endl;
            }
            else{
                LookForValue(&parent, value, found);
                if (found)
                {
                    cout << value << " exists in the Binary Tree." << endl;
                }else
                {
                    cout << value << " doesn't exist in the Binary Tree." << endl;
                }
            }
        }

};

int main()
{
    BinaryTree binaryTree(9);
    binaryTree.Add(5);
    binaryTree.Add(5);

    binaryTree.Exists(9);
    binaryTree.Exists(5);
}

At least function AddToOneTree is wrong and is the reason of undefined behaviour of the program至少函数AddToOneTree是错误的,是程序未定义行为的原因

For example in this code block例如在这个代码块中

if (parent->returnRightChild()==NULL)
{
    Node newNode(value);
    parent->setRightChild(&newNode);
    return;
}

you create a local variable newNode and its address asign to the pointer of right child.您创建一个局部变量newNode并将其地址分配给右孩子的指针。 However as the variable is local it is destroyed after the control leaves the code block and the corresponding pointer in the tree will be invalid.然而,由于变量是局部的,它在控件离开代码块后被销毁,树中相应的指针将无效。

You need to dynamically allocate nodes and add them to the tree.您需要动态分配节点并将它们添加到树中。

A better design is when the class BinaryTree contains a ponter to the head of the tree.更好的设计是,当类BinaryTree包含ponter树的头部。 Declare data member parent like像这样声明数据成员父级

class BinaryTree
{
    private:
        Node *parent;
             ^^^^^^^^
    //...

and correspondingly rewrite the class.:)并相应地重写该类。:)

You should replace this string:您应该替换此字符串:

void LookForValue(Node* parent, int value, bool found)

to this:对此:

void LookForValue(Node* parent, int value, bool &found)

or just set return value to bool in LookForValue function and write something like this:或者只是在LookForValue函数中将返回值设置为bool并编写如下内容:

found = LookForValue(&parent, value, found);

You have several issues in your code.您的代码中有几个问题。

The first one is that the boolean found is never returned by the LookForValue function.第一个是LookForValue函数永远不会返回找到的布尔值。 You can either change bool found to bool & found so that you do not have to return anything or change the return type of LookForValue to bool in which case you'll need to change your code to something like this:您可以将 bool found 更改为 bool & found 以便您不必返回任何内容,或者将LookForValue的返回类型LookForValuebool在这种情况下,您需要将代码更改为如下所示:

bool LookForValue(Node* parent, int value, bool found)
{
            if (value>parent->getValue())
            {
                if (parent->returnRightChild()!=NULL)
                {
                    if (parent->returnRightChild()->getValue()==value)
                    {
                        return true ;
                    }
                    else
                    {
                        LookForValue(parent->returnRightChild(), value, found);
                    }
                }
            }
            else if (value<parent->getValue())
            {
                if (parent->returnLeftChild()!=NULL)
                {
                    if (parent->returnLeftChild()->getValue()==value)
                    {
                        return true ;
                    }
                    else
                    {
                        LookForValue(parent->returnLeftChild(), value, found);
                    }
                }
            }
}

If you change the return type please also think about changing one line in your Exists function just after the else :如果您更改返回类型,请考虑在您的Exists函数中更改else之后的一行:

found = LookForValue(&parent, value, found);

I haven't tested the code yet so there might be other issues still.我还没有测试代码,所以可能还有其他问题。

The next time you face such an issue, I suggest trying to use gdb as it will probably help in detecting what your code is really doing so that you can figure out what may be wrong.下次遇到这样的问题时,我建议尝试使用 gdb,因为它可能有助于检测您的代码真正在做什么,以便您可以找出可能出错的地方。 For instance here, you could have seen that the found was never set to true in your Exists function just by "printing" step by step the value of your found variable.例如,在这里,您可以看到,仅通过逐步“打印”您的found变量的值,您的Exists函数中的 found 从未设置为 true 。

Also, I think the way you designed your classes is not really good.另外,我认为您设计课程的方式并不是很好。 Parent should be a pointer, pointing to the root of the tree. Parent 应该是一个指针,指向树的根。 I would suggest a complete re-designing of your code.我建议您完全重新设计您的代码。 You can find some good implementations online that you can be your code upon.你可以在网上找到一些很好的实现,你可以将它们作为你的代码。

Finally the goto is definitely a bad idea... I would get rid of that too.最后 goto 绝对是一个坏主意......我也会摆脱它。

void LookForValue(Node* parent, int value, bool found)

You are passing found by value.您正在通过值found That means the value will be copied.这意味着该值将被复制。 When you change found inside of the method LookForValue you are only changing this copy.当您在LookForValue方法内部更改found ,您只是在更改此副本。

void LookForValue(Node* parent, int value, bool& found)

This will pass found by reference, so if you change it inside of LookForValue the original in the Exists method will be changed as well.这将通过引用传递 found,因此如果您在LookForValue更改它, Exists方法中的原始值也将更改。

You can also just return a bool value like this:你也可以像这样返回一个 bool 值:

bool LookForValue(Node* parent, int value, bool &found)

And then just write return true;然后只写return true; instead of代替

found= true;
goto HERE;

That way you also get rid of the goto.这样你也可以摆脱 goto。

thanks for everyone.谢谢大家。 i've changed passing found by reference and allocated memeory using "new" for new nods.This now works!!我已经更改了通过引用找到的传递并使用“new”为新点头分配了内存。现在可以使用了!!

#include <iostream>

using namespace std;


class Node
{
    private:
        int _value;
        Node* left;
        Node* right;

    public:
        Node(int value):_value(value), left(NULL), right(NULL)
        {
        }
        Node* returnLeftChild()
        {
            return left;
        }
        Node* returnRightChild()
        {
            return right;
        }
        void setLeftChild(Node* l)
        {
            left=l;
        }
        void setRightChild(Node* r)
        {
            right=r;
        }
        int getValue()
        {
            return _value;
        }
};

class BinaryTree
{
    private:
        Node parent;
        void AddToOneTree(Node* parent, int value)
        {
            if (value==parent->getValue())
            {
                return;
            }
            if (value>parent->getValue())
            {
                if (parent->returnRightChild()==NULL)
                {
                    Node* newNode=new Node(value);
                    parent->setRightChild(newNode);
                    return;
                }
                else
                {
                    AddToOneTree(parent->returnRightChild(), value);
                }
            }
            if (value<parent->getValue())
            {
                if (parent->returnLeftChild()==NULL)
                {
                    Node* newNode=new Node(value);
                    parent->setLeftChild(newNode);
                    return;
                }
                else
                {
                    AddToOneTree(parent->returnLeftChild(), value);
                }
            }           
        }


        void LookForValue(Node* parent, int value, bool &found)
        {
            if (value>parent->getValue())
            {
                if (parent->returnRightChild()!=NULL)
                {
                    if (parent->returnRightChild()->getValue()==value)
                    {
                        found= true;
                        goto HERE;
                    }
                    else
                    {
                        LookForValue(parent->returnRightChild(), value, found);
                    }
                }
            }
            else if (value<parent->getValue())
            {
                if (parent->returnLeftChild()!=NULL)
                {
                    if (parent->returnLeftChild()->getValue()==value)
                    {
                        found= true;
                        goto HERE;
                    }
                    else
                    {
                        LookForValue(parent->returnLeftChild(), value, found);
                    }
                }
            }
            HERE:;
        }

    public:
        BinaryTree(int parentValue):parent(parentValue)
        {   
        }

        void Add(int value)
        {
            AddToOneTree(&parent, value);
        }

            void Exists(int value)
        {
            bool found = false;
            if (parent.getValue()==value)
            {
                cout << value << " exists in the Binary Tree." << endl;
            }
            else{
                LookForValue(&parent, value, found);
                if (found)
                {
                    cout << value << " exists in the Binary Tree." << endl;
                }else
                {
                    cout << value << " doesn't exist in the Binary Tree." << endl;
                }
            }
        }

};

int main()
{
    BinaryTree binaryTree(9);
    binaryTree.Add(5);
    binaryTree.Add(6);
    binaryTree.Add(1);
    binaryTree.Add(15);
    binaryTree.Add(13);
    binaryTree.Add(2);
    binaryTree.Add(2);
    binaryTree.Add(0);
    binaryTree.Add(4);

    binaryTree.Exists(9);
    binaryTree.Exists(5);
    binaryTree.Exists(6);
    binaryTree.Exists(1);
    binaryTree.Exists(15);
    binaryTree.Exists(13);
    binaryTree.Exists(2);
    binaryTree.Exists(2);
    binaryTree.Exists(0);
    binaryTree.Exists(4);
    binaryTree.Exists(11);

    binaryTree.Exists(412);

    binaryTree.Exists(40);


}

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

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