C++ 二叉搜索树中求最小和的算法改进
我编写了以下函数以查找二叉搜索树中任何路径的最小和:C++ 二叉搜索树中求最小和的算法改进,c++,algorithm,performance,optimization,binary-search-tree,C++,Algorithm,Performance,Optimization,Binary Search Tree,我编写了以下函数以查找二叉搜索树中任何路径的最小和: int minSumPath(TreeNode* root) { if(root==NULL) return 0; int sum = root->value; if(root->left!=NULL && root->right!=NULL) sum += min(minSumPath(root->left),minSumPath(root-&
int minSumPath(TreeNode* root) {
if(root==NULL)
return 0;
int sum = root->value;
if(root->left!=NULL && root->right!=NULL)
sum += min(minSumPath(root->left),minSumPath(root->right));
else
if(root->left==NULL)
sum += minSumPath(root->right);
else
sum += minSumPath(root->left);
return sum;
}
虽然上面的代码生成了正确的输出,但我觉得我并没有利用它是一个二叉搜索树(BST)而不仅仅是一个二叉树这一事实
在BST中,左子节点小于根节点和右节点,所以逻辑上只能考虑每个根的左子节点;但是,如果BST在右边只有一个子节点(比如说值为10),在左边有多个子节点(sum>10),该怎么办
在这种情况下,最小总和为10(位于右侧) 如果有,我将如何利用BST属性?还有,我可以在我的方法中使用的其他优化吗注意:编辑代码以解决错误 在某些情况下,知情搜索可能会有所帮助。
在最坏的情况下,计算成本与算法完全相同 例如:
int minSumPathOpt(TreeNode* root) {
if(root == nullptr) return 0;
int sum = -1;
std::stack<std::pair<TreeNode*, int>> todo;
todo.push(std::make_pair(root, 0));
while(not todo.empty()) {
std::pair<TreeNode*, int> curr = todo.top();
todo.pop();
TreeNode *node = curr.first;
int part = curr.second + node->value;
if(sum == -1 || part < sum) {
if(!node->left && !node->right) {
sum = part;
} else {
if(node->right) todo.push(std::make_pair(node->right, part));
if(node->left) todo.push(std::make_pair(node->left, part));
}
}
}
return sum;
}
int minSumPathOpt(TreeNode*root){
if(root==nullptr)返回0;
整数和=-1;
std::堆栈todo;
todo.push(std::make_pair(root,0));
while(不是todo.empty()){
std::pair curr=todo.top();
todo.pop();
TreeNode*node=curr.first;
int part=当前秒+节点->值;
如果(总和==-1 | |部分<总和){
如果(!node->left&&!node->right){
总和=部分;
}否则{
if(node->right)todo.push(std::make_pair(node->right,part));
如果(节点->左)todo.push(标准::生成对(节点->左,零件));
}
}
}
回报金额;
}
基本思想是在执行DFS时跟踪当前最小值。这将使您有机会在根的值之和已经大于当前最小值时修剪整个子树。此外,在查看右树之前先查看左树有助于最大化结果(确实没有保证,但这是一个好主意,因为BST是如何定义的) 请参阅上两种方法的比较。
正如您所看到的,第二个函数并没有探究所有不太有前途的树 @user3112926,虽然我完全同意你,先生,我正在寻求算法改进。我不知道为什么我看不到函数返回除零以外的任何其他值。作为一个很好的代码改进:既然你已经检查了
root
forNULL
,你可以省略其他级别的NULL检查,只需使用NULL
s中的s调用minSumPath
left
或right
。是的,但是在下一个递归步骤中root->left
和root->right
将是新的root
,再次检查NULL
。不过这个问题很有趣。一定有办法利用BST的结构。谢谢你的回答。你看到我们可以利用BST属性的一些方法了吗?@user6490375我怀疑修剪没有希望的子树是你能做的最好的方法。BST不一定会最小化特定子树上的结果。您可以很容易地构造一棵左子树上的路径最短,右子树上的路径最短的树。这些可能会挫败任何利用较低值位于左侧等事实的企图。