C++ 列出并计算二叉树从根到叶的最大权重路径

C++ 列出并计算二叉树从根到叶的最大权重路径,c++,binary-tree,graph-algorithm,C++,Binary Tree,Graph Algorithm,我必须返回节点的数量和从根到某个叶的最大权重路径的权重。请注意,该树不是二叉搜索树,而是未排序的 i、 e: 然后,我必须返回整数6+6+19=31并打印节点6-6-19 这是我的代码: int heavierPath ( Node * tree ) { if ( ! tree ) return 0; int leftWeight = heavierPath( tree->left ); int rightWeight= heavierPath( tree->

我必须返回节点的数量和从根到某个叶的最大权重路径的权重。请注意,该树不是二叉搜索树,而是未排序的

i、 e:

然后,我必须返回整数
6+6+19=31
并打印节点
6-6-19

这是我的代码:

int heavierPath ( Node * tree ) {
    if ( ! tree ) return 0;

    int leftWeight = heavierPath( tree->left );
    int rightWeight= heavierPath( tree->right );

    if ( leftWeight >= rightWeight ) {
        if ( tree->left )
            cout << tree->left->value << endl;
        return tree->value + leftWeight;
    }
    else {
        cout << tree->right->value << endl;

        return tree->value + rightWeight;
    }
};
int heavierPath(节点*树){
如果(!tree)返回0;
int leftWeight=heavierPath(树->左);
int rightWeight=heavierPath(树->右);
如果(左权重>=右权重){
如果(树->左)
cout left->value value+leftWeight;
}
否则{
cout right->value value+rightWeight;
}
};
结果是
31
,但我看到终端中的所有节点值

如何修复它并仅打印位于较重路径中的元素?(仅递归)


谢谢

我的建议是使用两个函数,第一个函数将查找从根到叶的路径最大的叶。因此,假设您有指向此类叶的指针,这里是打印路径的函数

bool print(struct node *r, struct node *leaf)
{

    if (r == NULL)
        return false;
    //will print if it is leaf or on path to leaf
    if (r == leaf || print(r->left, leaf) || print(r->right, leaf) )
    {
        printf("%d ", r->val); // this will print in reverse order
                               // if you want to print from root, store values in stack and then print the value after the function call
        return true;
    }

    return false;
}

这似乎在我编辑它之后起作用

以:为例

你的问题:

将该图视为:

     6
   /   \
  9     6
 /     / \
3     1   19
为每个节点编号,以便:

     0
   /   \
  1     2
 /     / \
3     4   5
考虑一下您位于节点1的情况。 您要求提供更好的路径,该路径将为您提供
leftWeight=3
righweight=0
,然后打印“更好”路径,3。这不是最终结果的一部分

解决方案

为了解决这个问题,我在
retstruct
中传递了额外的数据,其中包含
路径
(到目前为止最重的路径)、
(以便于打印)、
求和
(以确定更好的路径)

然后我将函数更改为:

retstruct* heavierPath ( Node * tree ) {
    if ( ! tree ) return new retstruct();

    //Get both paths
    retstruct* leftWeight = heavierPath( tree->left );
    retstruct* rightWeight= heavierPath( tree->right );

    //Find the "heavier" path
    if ( leftWeight->sum >= rightWeight->sum ) {
        //Delete lighter path
        delete_retstruct(rightWeight);
        //Pass up the better path with the correct data
        return new retstruct(leftWeight, tree->value, tree->value + leftWeight->sum);
    } else {
        //Delete lighter path
        delete_retstruct(leftWeight);
        //Pass up the better path with the correct data
        return new retstruct(rightWeight, tree->value, tree->value + rightWeight->sum);
    }
};
添加了delete_retstruct函数:

void delete_retstruct (retstruct* path) {
    if (path->path == NULL) {
        delete path;
    } else {
        delete_retstruct(path->path);
    }
}
void printPath (retstruct* path) {
    if (path->path != NULL) {
        std::cout << " - " << path->value;
        printPath(path->path);
    }
}
和printPath函数:

void delete_retstruct (retstruct* path) {
    if (path->path == NULL) {
        delete path;
    } else {
        delete_retstruct(path->path);
    }
}
void printPath (retstruct* path) {
    if (path->path != NULL) {
        std::cout << " - " << path->value;
        printPath(path->path);
    }
}

问题是,您正在混合打印节点和查找总和。后者必须访问所有子节点,而打印只需访问路径中的子节点。 以下是一个可能的解决方案:

#include <iostream>
#include <unordered_map>

struct Node
{
    Node(int value = 0, Node* left = nullptr, Node* right = nullptr) :
        value{value},
        left{left},
        right{right}
    {}

    int value;
    Node* left;
    Node* right;
};

std::unordered_map<Node*, int> map;

int pathSum(Node* node)
{
    if (node == nullptr)
    {
        return 0;
    }
    else if (map.find(node) == map.end())
    {
        return (pathSum(node->left) > pathSum(node->right)) 
                ? (map[node] = node->value + pathSum(node->left)) 
                : (map[node] = node->value + pathSum(node->right));
    }
    else
    {
        return map[node];
    }
}

void printPath(Node* node)
{
    if (node == nullptr)
    {
        return;
    }
    std::cout << node->value << std::endl;
    if (pathSum(node->left) > pathSum(node->right))
    {
        printPath(node->left);
    }
    else
    {
        printPath(node->right);
    }
}

int main() {

    Node* tree = new Node(6, 
                             new Node(9,
                                         new Node(3)),
                             new Node(6,
                                         new Node(1),
                                         new Node(19)));

    std::cout << "Biggest Sum: " << pathSum(tree) << std::endl;
    std::cout << "Biggest Sum Path: " << std::endl;
    printPath(tree);

    return 0;

}
#包括
#包括
结构体类型
{
节点(int值=0,节点*左=nullptr,节点*右=nullptr):
值{value},
左{左},
右{右}
{}
int值;
节点*左;
节点*右;
};
std::无序地图;
int路径和(节点*节点)
{
if(node==nullptr)
{
返回0;
}
else if(map.find(node)=map.end())
{
返回(路径和(节点->左)>路径和(节点->右))
?(映射[节点]=节点->值+路径和(节点->左))
:(映射[节点]=节点->值+路径和(节点->右侧));
}
其他的
{
返回映射[节点];
}
}
无效打印路径(节点*节点)
{
if(node==nullptr)
{
返回;
}
std::cout value left)>路径和(节点->右侧)
{
打印路径(节点->左侧);
}
其他的
{
打印路径(节点->右侧);
}
}
int main(){
节点*树=新节点(6,
新节点(9,
新节点(3)),
新节点(6,
新节点(1),
新节点(19));

std::cout此函数将打印所有节点!不,仅在从根节点到最重节点的路径上。因为如果部分位于该路径上,则它将为真。您是否尝试实现它?我没有检查。仔细观察函数。思考函数中的if何时为真?仅当路径到达所需的叶节点时。对不起,you是正确的。困难的部分实际上是找到节点。一旦你有了所需的节点,你就可以简单地遍历父节点,直到到达顶部。这就是我所做的,虽然op能够找到所需的叶节点,所以我只是帮你打印我的建议工作了吗?我已经测试过了,并且工作正常。
#include <iostream>
#include <unordered_map>

struct Node
{
    Node(int value = 0, Node* left = nullptr, Node* right = nullptr) :
        value{value},
        left{left},
        right{right}
    {}

    int value;
    Node* left;
    Node* right;
};

std::unordered_map<Node*, int> map;

int pathSum(Node* node)
{
    if (node == nullptr)
    {
        return 0;
    }
    else if (map.find(node) == map.end())
    {
        return (pathSum(node->left) > pathSum(node->right)) 
                ? (map[node] = node->value + pathSum(node->left)) 
                : (map[node] = node->value + pathSum(node->right));
    }
    else
    {
        return map[node];
    }
}

void printPath(Node* node)
{
    if (node == nullptr)
    {
        return;
    }
    std::cout << node->value << std::endl;
    if (pathSum(node->left) > pathSum(node->right))
    {
        printPath(node->left);
    }
    else
    {
        printPath(node->right);
    }
}

int main() {

    Node* tree = new Node(6, 
                             new Node(9,
                                         new Node(3)),
                             new Node(6,
                                         new Node(1),
                                         new Node(19)));

    std::cout << "Biggest Sum: " << pathSum(tree) << std::endl;
    std::cout << "Biggest Sum Path: " << std::endl;
    printPath(tree);

    return 0;

}