C ++: сумма всех значений узлов двоичного дерева - PullRequest
10 голосов
/ 24 сентября 2010

Я готовлюсь к собеседованию.Я застрял на одном из вопросов двоичного дерева:

Как мы можем вычислить сумму значений, присутствующих во всех узлах двоичного дерева?

Ответы [ 7 ]

24 голосов
/ 24 сентября 2010

Элегантное рекурсивное решение (в псевдокоде):

def sum (node):
    if node == NULL:
        return 0
    return node->value + sum (node->left) + sum (node->right)

тогда просто используйте:

total = sum (root)

Это правильно обрабатывает случай нулевого корневого узла.


И если вы хотите увидеть это в действии в C ++, вот код, использующий этот алгоритм. Во-первых, структура для узла и функция sum:

#include <iostream>

typedef struct sNode {
    int value;
    struct sNode *left;
    struct sNode *right;
} tNode;

int sum (tNode *node) {
    if (node == 0) return 0;
    return node->value + sum (node->left) + sum (node->right);
}

Тогда приведенный ниже код является тестовым кодом для вставки узлов:

static tNode *addNode (tNode *parent, char leftRight, int value) {
    tNode *node = new tNode();
    node->value = value;
    node->left = 0;
    node->right = 0;

    if (parent != 0) {
        if (leftRight == 'L') {
            parent->left = node;
        } else {
            parent->right = node;
        }
    }

    return node;
}

И, наконец, основная функция для построения следующего дерева, которое покрывает все допустимые возможности (пустой узел, узел с двумя дочерними элементами, узел без дочерних элементов, узел с одним правым дочерним элементом и узел с одним левым дочерним элементом) :

    10
   /  \
  7    20
 /       \
3         99
 \
  4
   \
    6

Код для построения этого дерева и представления суммы в различных точках показан здесь:

int main (void) {
    // Empty tree first.

    tNode *root = 0;

    std::cout << sum (root) << '\n';

    // Then a tree with single node (10).

    root = addNode (0, ' ', 10);

    std::cout << sum (root) << '\n';

    // Then one with two subnodes (10, 7, 20).

    addNode (root,'L',7);
    addNode (root,'R',20);

    std::cout << sum (root) << '\n';

    // Then, finally, the full tree as per above.

    addNode (root->left,'L',3);
    addNode (root->left->left,'R',4);
    addNode (root->left->left->right,'R',6);
    addNode (root->right,'R',99);

    std::cout << sum (root) << '\n';

    return 0;
}

Это выводит (правильный):

0
10
37
149
5 голосов
/ 24 сентября 2010

Пройдите по дереву в любом порядке (до, после, в). Вместо того, чтобы распечатать узел, рассчитать итог.

void sum(Node* root, int& total)  
{   
    if(root == NULL)
    {
         return;
    }    
    sum(root->left, total);    
    total = total + root->value;   
    sum(root->right, total);  
}  
int main()  
{  
    int total =0;  
    sum(root,total);  
    cout << total;  
}
4 голосов
/ 24 сентября 2010

Аналогично поиску в дереве, отображению каждого узла или любой другой операции в масштабе дерева: посетите текущий узел, посетите левое поддерево (рекурсивно) и посетите правое поддерево (рекурсивно).

По сути, что-то вроде этого:

int TreeNode::calculateSum() const
{
    int sum = this->value;

    if (this->left  != NULL) sum += this->left ->calculateSum();
    if (this->right != NULL) sum += this->right->calculateSum();

    return sum;
}

Из-за проверок if рекурсия, в конце концов, достигнет дна, когда достигнет узлов без левого или правого потомка (конечных узлов).

2 голосов
/ 24 декабря 2017
          50
       /     \
      30      70
     /  \    /  \
   20   40  60   80 

возвращается: 350

int Sum(struct node *root)
    {

       if(root->left == NULL && root->right== NULL)
            return root->key;

        int lvalue,rvalue;


        lvalue=Sum(root->left);
        rvalue=Sum(root->right);

        return root->key+lvalue+rvalue;

    }
2 голосов
/ 24 сентября 2010

Используйте один из методов обхода дерева (в порядке, предзаказе, после заказа), чтобы посетить каждый узел и сохранить сумму в переменной.это вики

2 голосов
/ 24 сентября 2010

Несмотря на то, что STL имеет более сложные и лаконичные механизмы для этого, он очень быстро добивается производительности, просто научившись использовать ручной цикл над контейнером, что-то вроде:

Tree::value_type total = Tree::value_type();
for (Tree::const_iterator i = tree.begin(); i != tree.end(); ++i)
    total += *i;

Это предполагает, что ваше двоичное дерево является STL :: map, или, если нет, вы предоставите концепцию итератора для своей собственной реализации ....

0 голосов
/ 12 января 2017
public int sum(Node root){
    if(root==null){
        return 0;
    }
    if(root.left == null && root.right==null){
        return root.key;
    }
    return sum(root.left)+sum(root.right)+root.key;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...