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