列出并计算从二叉树的根到叶的最重量路径

时间:2014-05-24 04:32:45

标签: c++ binary-tree graph-algorithm

我必须返回从根到一些叶子的节点数和最重量路径的权重。请注意,树不是二进制搜索树,未排序。

即:

     6
   /   \
  9     6
 /     / \
3     1   19

然后,我必须返回整数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;
    }
};

结果是31,但我看到了终端中的所有节点值。

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

谢谢!

3 个答案:

答案 0 :(得分:1)

这在编辑后似乎有效。

http://ideone.com/OGcyun为例。

您的问题:

将图表视为:

     6
   /   \
  9     6
 /     / \
3     1   19

为每个节点编号:

     0
   /   \
  1     2
 /     / \
3     4   5

考虑您在节点1的情况。 您需要更好的路径,它会为您提供leftWeight = 3rightweight = 0,并打印“更好”的路径,3。这不是最终结果的一部分。

解决方案

为了解决这个问题,我在retstruct中传递了其他数据,其中包含path(到目前为止最重的路径),value(使打印更容易) ,sum(以确定更好的路径)。

然后我将功能更改为:

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);
    }
}

和printPath函数:

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

这样使用:

retstruct* path = heavierPath(tree);

//Print sum
std::cout << "Sum: " << path->sum << std::endl;

//Print path
std::cout << "Path: " << path->value;
printPath(path->path);
std::cout << std::endl;

输出:

Sum: 31
Path: 6 - 6 - 19

答案 1 :(得分:0)

我的建议是制作两个函数,第一个函数将找到从root到它的路径最大的叶子。所以假设你有指向这种叶子的指针就是打印路径的函数。

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;
}

答案 2 :(得分:0)

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

#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;

}

在这样的递归解决方案中,最好缓存结果,因此std :: unordered_map。该代码已在Ideone进行了测试。