2010-09-24 14 views

Antwort

24

Die eleganten rekursive Lösung (in Pseudocode):

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

dann benutzen Sie einfach:

total = sum (root) 

Diese korrekt behandelt den Fall eines NULL-Wurzelknotens.


Und wenn Sie es in Aktion in C++ sehen möchten, hier ist ein Code mit diesem Algorithmus. Zuerst wird die Struktur für einen Knoten und die sum Funktion:

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

Dann unterhalb der Code ist ein Test-Harnisch-Code zum Einfügen von Knoten:

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

Und schließlich die wichtigste Funktion für den Aufbau der folgenden Baum, einer, der alle gültigen Möglichkeiten abdeckt (leerer Knoten, Knoten mit zwei Kindern, Knoten ohne Kinder, Knoten mit einem rechten Kind und Knoten mit einem linken Kind):

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

Der Code, den Baum zu konstruieren und die Summe an verschiedenen Punkten berichten wird hier gezeigt:

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

Diese Ausgänge (die richtigen):

0 
10 
37 
149 
+0

sollte nicht die letzte Zeile sein Return Summe (node-> left) + sum (node-> right) + node-> val; –

+0

Ja, habe mich mitten im Schnitt gefangen. Ich hatte mich gerade gefragt, woher der Wert des aktuellen Knotens kam ... Fixed now :-) – paxdiablo

+0

Vielen Dank Paxdiablo. Übrigens, das ist ein O (n) Algorithmus richtig? Da es jeden Knoten nur einmal besucht. – csguy11

4

Auf die gleiche Weise wie Sie den Baum durchsuchen oder jeden Knoten oder eine andere baumweite Operation anzeigen: Besuchen Sie den aktuellen Knoten, besuchen Sie den linken Teilbaum (rekursiv) und besuchen Sie den rechten Teilbaum (rekursiv) .

Im Grunde so etwas wie diese:

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

Wegen der if prüft die Rekursion wird schließlich unten, wenn es Knoten ohne nach links oder rechts Kindern erreicht (Blattknoten).

2

Während die STL komplexe und präzise Mechanismen hat, dies zu tun, es ist ein sehr schnelles rodet, um die Produktivität eine manuelle Schleife über einen Behälter zu verwenden, nur um zu lernen, so etwas wie:

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

Dies setzt voraus, die Binärdatei tree ist eine STL :: map, oder falls nicht, stellst du ein Iteratorkonzept für deine eigene Implementierung zur Verfügung ....

+0

Ich würde dies als Antwort nicht geben, sagte Interviewfrage –

+0

Ich wünschte, dieser Gedanke mein erstes waren. +1. Ein Baum in C++ kann nur eine andere Sequenz sein. – Potatoswatter

+0

@Eli: Der Eindruck hängt von Phrasierung ab. Asked "sum die Knoten in einem binären Baum", sagend "in C++ die STD std :: map <> ist der binäre Baum des Standards; unter Verwendung seiner öffentlichen Schnittstelle ist eine einfache, allgemeine Art Knoten zu addieren XXX. Es ist gleichermaßen anwendbar auf andere Iteratoren -sporting Abstraktionen. " dann denke ich, das wäre eine gute Antwort. Zu wissen, dass Menschen zuerst auf STL-Niveau (oder höherem Design-Muster-Level, wo zutreffend) denken, ist beruhigend. Im schlimmsten Fall kann der Interviewer den rekursiven Ansatz, der in anderen Antworten auf diese Frage beschrieben wird, expliziter aufrufen oder die beiden vergleichen. –

2

Verwende eine der Tree Traversal Techniken (In-Order, Vorbestellung, Nachbestellung) um jeden Knoten zu besuchen und die Summe in einer Variablen zu speichern.

Sie können weitere Details zu dem Baumdurchlauf finden in dieser wiki

5

Traverse Baum in beliebiger Reihenfolge (pre, Post, im). Anstatt den Knoten zu drucken, berechnen Sie die Summe.

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; 
} 
0
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; 
} 
+3

Beantworten von Fragen ist gut, aber diese Frage hat bereits Antworten mit sehr ähnlichem Code. Jede neue Antwort sollte andere Methoden hinzufügen oder eine bessere Erklärung dafür liefern, warum die Methode gut ist. Ein Code, der nur antwortet, wie dieser, der einfach wiederholt, was bereits zur Verfügung gestellt wurde, fügt nichts nützliches hinzu. – AdrianHHH

2
  50 
    / \ 
     30  70 
    /\ /\ 
    20 40 60 80 

kehrt: 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; 

    } 
Verwandte Themen