Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 二叉搜索树中求最小和的算法改进_C++_Algorithm_Performance_Optimization_Binary Search Tree - Fatal编程技术网

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
for
NULL
,你可以省略其他级别的NULL检查,只需使用
NULL
s中的
s调用
minSumPath
left
right
。是的,但是在下一个递归步骤中
root->left
root->right
将是新的
root
,再次检查
NULL
。不过这个问题很有趣。一定有办法利用BST的结构。谢谢你的回答。你看到我们可以利用BST属性的一些方法了吗?@user6490375我怀疑修剪没有希望的子树是你能做的最好的方法。BST不一定会最小化特定子树上的结果。您可以很容易地构造一棵左子树上的路径最短,右子树上的路径最短的树。这些可能会挫败任何利用较低值位于左侧等事实的企图。