C++ 我如何在C+;中缩短这个琐碎的数据树算法+;?

C++ 我如何在C+;中缩短这个琐碎的数据树算法+;?,c++,binary-search-tree,C++,Binary Search Tree,它创建一个数据树和一个“随机”/“伪随机数”。 然后,它会查找“随机”生成的数字的路径,以及是否找到了整个数字。 当然有更好的办法,但我就是想不出一个。 此外,我看到了一个bug,但它甚至不值得修复,因为无论如何都必须有更好的方法(我的意思是,无论出于什么原因,整数“in”大于或小于10或0) 我就是找不到关于它的任何东西。难道这根本不可能吗 struct节点{ int数据; 结构节点*左; 结构节点*右; 节点(int-val) { 数据=val; 左=空; 右=空; } }; 节点*buil

它创建一个数据树和一个“随机”/“伪随机数”。 然后,它会查找“随机”生成的数字的路径,以及是否找到了整个数字。 当然有更好的办法,但我就是想不出一个。 此外,我看到了一个bug,但它甚至不值得修复,因为无论如何都必须有更好的方法(我的意思是,无论出于什么原因,整数“in”大于或小于10或0)

我就是找不到关于它的任何东西。难道这根本不可能吗

struct节点{
int数据;
结构节点*左;
结构节点*右;
节点(int-val)
{
数据=val;
左=空;
右=空;
}
};
节点*build(){
结构节点*根=新节点(5);
根->右=新节点(3);
根->左=新节点(7);
根->右->右=新节点(1);
根->右->左=新节点(4);
根->右->右->右=新节点(0);
根->右->右->左=新节点(2);
根->左->右=新节点(6);
根->左->左=新节点(9);
根->左->左->右=新节点(8);
根->左->左->左=新节点(10);
返回根;
}
无效工作程序(int-in,节点*根){
bool-found=false;
字符串路径=”;
int-val=0;
如果(在>根->数据中){
如果(在>根->左->数据中){
如果(在>根->左->左->数据中){
发现=真;
path=“根->左->左->左”;
val=根->左->左->左->数据;
}
else if(在left->left->data中){
发现=真;
path=“根->左->左->右”;
val=根->左->左->右->数据;
}
否则{
发现=真;
path=“根->左->左”;
val=根->左->左->数据;
}
}
else if(在left->data中){
发现=真;
path=“根->左->右”;
val=根->左->右->数据;
}
否则{
发现=真;
path=“根->左”;
val=根->左->数据;
}
}
else if(在data中){
如果(在>根->右->数据中){
发现=真;
path=“根->右->左”;
val=根->右->左->数据;
}
else if(在right->data中){
如果(在>根->右->右->数据中){
发现=真;
path=“根->右->右->左”;
val=根->右->右->左->数据;
}
else if(在right->right->data中){
发现=真;
path=“根->右->右->右”;
val=根->右->右->右->数据;
}
否则{
发现=真;
path=“根->右->右”;
val=根->右->右->数据;
}
}
否则{
发现=真;
path=“根->右”;
val=根->右->数据;
}
}
否则{
发现=真;
path=“root”;
val=根->数据;
}
```
老实说,你的“worker”函数使用了大量的“if…else if…else”样式,这可能会使你的算法难以扩展。也许你可以试试这段代码

Node * prt = root;
string val,path="root"; 
while(prt){ 
 if(prt.data>in){
  path+="->right";
  prt=prt->right;} 
 else if(prt.date<in){
  path+="->left";
  prt=prt->left;} 
 else{
  break;} 
}
val=root+"->data";
Node*prt=root;
字符串val,path=“root”;
while(prt){
如果(prt.data>in){
路径+=“->右”;
prt=prt->right;}
else if(prt.dateleft;}
否则{
中断;}
}
val=根+“->数据”;

因此,如果您必须编写自己的二叉树,而不是使用
std::set
,那么您就不想硬编码树中的所有路径-可能有数千个节点,您会发现仅处理11个节点是多么痛苦

有两种方法可以解决这个问题:可以使用迭代(while循环)遍历二叉树,也可以使用递归。有些问题在迭代中更简单,有些问题在递归中更容易解决。所以我用两种方法都做了,以便您可以比较

使用while循环:

#include <iostream>
#include <string>

struct Node {
    int data;
    Node* left;
    Node* right;

    Node(int data) : data(data), left(NULL), right(NULL) {}
};

struct AddResult
{
    Node *node;
    bool inserted;
    std::string path;
    
    AddResult(Node *node, bool inserted, std::string path) : node(node), inserted(inserted), path(path) {}
};

AddResult add(Node* node, int value)
{
    bool inserted = false;
    std::string path = "root";

    while (node != NULL && value != node->data)
    {
        if (value > node->data)
        {
            // add to the right
            if (node->right == NULL)
            {
                node->right = new Node(value);
                inserted = true;
            }
            path = path + "->right";
            node = node->right;
        }
        else
        {
            // add to the left
            if (node->left == NULL)
            {
                node->left = new Node(value);
                inserted = true;
            }
            path = path + "->left";
            node = node->left;
        }
    }
    return AddResult(node, inserted, path);
}

struct FindResult
{
    Node *node;
    bool found;
    std::string path;
    
    FindResult(Node *node, bool found, std::string path) : node(node), found(found), path(path) {}
};

FindResult find(Node* node, int value)
{
    bool found = true;
    std::string path = "root";

    while (node != NULL && value != node->data)
    {
        if (value > node->data)
        {
            // add to the right
            if (node->right == NULL)
                found = false;

            path = path + "->right";
            node = node->right;
        }
        else
        {
            // add to the left
            if (node->left == NULL)
                found = false;
                
            path = path + "->left";
            node = node->left;
        }
    }
    return FindResult(node, found, path);
}

int main()
{
    Node *root = new Node(5);
    printf("%d was made the root of the tree\n", 5);

    // add all the odd values from 1 to 10 inclusive
    for(int i=1; i<=10; i+=2)
    {
        AddResult result = add(root,i);
        if (result.inserted == false)
            printf("%d was already in the tree at: %s\n", i, result.path.c_str());
        else
            printf("%d was added to the tree at: %s\n", i, result.path.c_str());
    }
    // add all the even values from 1 to 10 inclusive
    for(int i=0; i<=10; i+=2)
    {
        AddResult result = add(root,i);
        if (result.inserted == false)
            printf("%d was already in the tree at: %s\n", i, result.path.c_str());
        else
            printf("%d was added to the tree at: %s\n", i, result.path.c_str());
    }

    puts("");

    // find all the values from -1 to 12 inclusive
    for(int i=-1; i<=12; i++)
    {
        FindResult result = find(root,i);
        if (result.found == false)
            printf("%d was not found in the tree\n", i);
        else
            printf("%d was Found in the tree at %s\n", i, result.path.c_str());
    }


    return 0;
}

中尝试一次检查一个节点,但是如果有1000个节点怎么办?你需要使用递归来构建和搜索一棵树。函数应该查看当前节点,然后为每个子自己调用。另外,C++语言提供了广泛的“容器类”选择。当然包括树,特别是这样你就不必自己编写和调试它们了。虽然这可能是一个“有价值的学术练习”要从头开始写这样的算法,只需了解它们的工作原理,就可以了。用C++,你可以很容易地站在巨人的肩膀上。抓取一个类,简单地使用它,知道它会起作用。是的,这就是为什么我确信一个更好的解决方案必须存在的原因。我怎么能用递归来解决这个问题?谢谢!这简直就是F。或者练习是^^你不需要使用递归,你可以像其他答案建议的那样使用while循环。也许我应该在我的答案中添加一个例子……这是一个详细的答案,回答了我所有的问题!非常感谢!我不知所措。
#include <iostream>
#include <string>

struct Node {
    int data;
    Node* left;
    Node* right;

    Node(int data) : data(data), left(NULL), right(NULL) {}
};

struct AddResult
{
    Node *node;
    bool inserted;
    std::string path;
    
    AddResult(Node *node, bool inserted, std::string path) : node(node), inserted(inserted), path(path) {}
};

AddResult add(Node* node, int value, std::string path = "root")
{
    if (value == node->data)
        return AddResult(node, false, path); // already in tree

    if (value > node->data)
    {
        // add to the right
        if (node->right != NULL)
            return add(node->right, value, path + "->right");
        else
        {
            node->right = new Node(value);
            return AddResult(node->right, true, path + "->right");
        }
    }
    else
    {
        // add to the left
        if (node->left != NULL)
            return add(node->left, value, path + "->left");
        else
        {
            node->left = new Node(value);
            return AddResult(node->left, true, path + "->left");
        }
    }
}

struct FindResult
{
    Node *node;
    bool found;
    std::string path;
    
    FindResult(Node *node, bool found, std::string path) : node(node), found(found), path(path) {}
};

FindResult find(Node* node, int value, std::string path = "root")
{
    if (value == node->data)
        return FindResult(node,true,path);
    
    if (value > node->data)
    {
        // add to the right
        if (node->right != NULL)
            return find(node->right, value, path + "->right");
        else
            return FindResult(NULL,false,path);
    }
    else
    {
        // add to the left
        if (node->left != NULL)
            return find(node->left, value, path + "->left");
        else
            return FindResult(NULL,false,path);
    }
}

int main()
{
    Node *root = new Node(5);
    printf("%d was made the root of the tree\n", 5);

    // add all the odd values from 1 to 10 inclusive
    for(int i=1; i<=10; i+=2)
    {
        AddResult result = add(root,i);
        if (result.inserted == false)
            printf("%d was already in the tree at: %s\n", i, result.path.c_str());
        else
            printf("%d was added to the tree at: %s\n", i, result.path.c_str());
    }
    // add all the even values from 1 to 10 inclusive
    for(int i=0; i<=10; i+=2)
    {
        AddResult result = add(root,i);
        if (result.inserted == false)
            printf("%d was already in the tree at: %s\n", i, result.path.c_str());
        else
            printf("%d was added to the tree at: %s\n", i, result.path.c_str());
    }

    puts("");

    // find all the values from -1 to 12 inclusive
    for(int i=-1; i<=12; i++)
    {
        FindResult result = find(root,i);
        if (result.found == false)
            printf("%d was not found in the tree\n", i);
        else
            printf("%d was Found in the tree at %s\n", i, result.path.c_str());
    }


    return 0;
}
#include <stdio.h>
#include <set>

int main()
{
    std::set<int> tree;

    // let's add an item now so we can see what happens if we add it again later    
    auto result = tree.insert(5);
    printf("%d was added to the tree: %d\n", 5, *result.first);

    // add all the values from 0 to 10 inclusive
    for(int i=0; i<=10; i++)
    {
        auto result = tree.insert(i);
        if (result.second == false)
            printf("%d was already in the tree: %d\n", i, *result.first);
        else
            printf("%d was added to the tree: %d\n", i, *result.first);
    }

    puts("");

    // find all the values from -1 to 12 inclusive
    for(int i=-1; i<=12; i++)
    {
        auto result = tree.find(i);
        if (result == tree.end())
            printf("%d was not found in the tree\n", i);
        else
            printf("%d was Found in the tree: %d\n", i, *result);
    }


    return 0;
}