2016-04-01 14 views
-1

Ich schrieb die folgende Funktion in C, die 1 zurückgibt, wenn das Element tatsächlich im Binärbaum ist und 0 andernfalls.Suche nach Element im Binärbaum, Funktion liefert immer 0

int isElementInBinaryTree(BinaryTreeNode *root, int search_item) { 
if(root) { 
    if(search_item == root -> data) return 1; 
    isElementInBinaryTree(root -> left, search_item); 
    isElementInBinaryTree(root -> right, search_item); 
} 

return 0; 
} 

Zuerst gebe ich die Funktion zu sehen, ob die Wurzel ist, wenn es ist, ich mir die Daten an dieser Wurzel und vergleichen Sie es mit dem search_item. Wenn es wahr ist, gebe ich einfach 1 zurück und verlasse es, ansonsten fahre ich mit der Vorbestellung fort. Warum bekomme ich immer eine 0 zurück? Selbst wenn der Artikel im Binärbaum ist?

Antwort

4

ändern diese Linien

isElementInBinaryTree(root -> left, search_item); 
isElementInBinaryTree(root -> right, search_item); 

das Ergebnis zurück.

heißt

return isElementInBinaryTree(root -> left, search_item) || isElementInBinaryTree(root -> right, search_item); 

Wenn das Element in der LHS gefunden wird true zurück - sonst wird es RHS versuchen. Beachten Sie die Verwendung von || - Kurzschluss Betreiber

EDIT

Kann diese erhalten in einer return-Anweisung

int isElementInBinaryTree(BinaryTreeNode *root, int search_item) 
{ 
    return root ? (search_item == root -> data || isElementInBinaryTree(root -> left, search_item) || isElementInBinaryTree(root -> right, search_item)) : 0; 
} 

EDIT 2

eine Annahme zu machen, die Sie suchen: ein Element, das verwendet wird, um den Baum mit LHS zu ordnen, der kleiner als und der RHS größer als ist.

sollte der Code aussehen

int isElementInBinaryTree(BinaryTreeNode *root, int search_item) 
{ 
    if(root) { 
     // Assuming that most of the items in the tree are not the search item 
     // best to check first if we need to search LHS or RHS - these 
     // events are more likely than the item being found! 
     if (search_item < root -> data) return isElementInBinaryTree(root -> left, search_item); 
     if (search_item > root -> data) return isElementInBinaryTree(root -> right, search_item); 
     return 1; // We have found it 
    } 

    return 0; 
} 
+1

Auch die linke rekursiv Suche und dann negiert rechts vollständig den Punkt des binären Baums mit. Stattdessen sollte es eine Wahl treffen, in das linke ODER das rechte zurückzuspringen, abhängig davon, ob der aktuelle Wert größer oder kleiner ist als der, nach dem Sie suchen. – GrahamS

+0

@GrahamS - Die Suche kann aufgrund der Suche nach einem Element in dem Knoten, der nicht in der Reihenfolge für die Konstruktion des Binärbaums verwendet wird –

+0

sein. Das OP vergleicht die 'node-> data' mit dem' search_item' also I Ich denke, es ist sicher anzunehmen, dass der binäre Baum in Bezug auf "node-> data" sortiert ist und wenn dies nicht der Fall ist, was ist der Sinn davon, dass er ein binärer Baum ist? – GrahamS

4

Sie zu isElementInBinaryTree nicht den Rückgabewert der rekursiven Aufrufe verwenden. Sie müssen das Ergebnis der rekursiven Aufrufe an den obersten Aufruf weitergeben. Wie es jetzt ist, wird es nur 1 zurückgeben, wenn das Zielobjekt im Wurzelknoten ist.

So:

int isElementInBinaryTree(BinaryTreeNode *root, int search_item) 
{ 
    if(root) { 
     if (search_item == root -> data) return 1; 
     if (isElementInBinaryTree(root -> left, search_item)) return 1; 
     if (isElementInBinaryTree(root -> right, search_item)) return 1; 
    } 

    return 0; 
} 
+0

Bitte beachten Sie, dass die dritte Bedingungsprüfung redundant ist, einfach das Ergebnis aus dem Anruf zurückgeben. – Ravi

+0

Es gibt jedoch Vor- und Nachteile dieses Ansatzes, der von der Reihenfolge der Elemente im Baum abhängt. Ihr Ansatz kann den linken Baum durchqueren, selbst wenn sich das Element zufällig in der rechten Unterstruktur befindet, weil es in der Aufrufsequenz Vorrang hat, die Ok läuft, aber zusätzliche Suche benötigt. In ähnlicher Weise würde der von @ grahams unten vorgeschlagene Ansatz das Suchelement zweimal mit dem Wurzelknotendatum vergleichen, eins vor dem Eintritt in den Unterbaum, eins nach dem Eintritt in den Unterbaum, falls dies überhaupt existiert, aber das Durchsuchen des Unterbaums vermeidet wenn es nicht da ist. So etwas wird nur in edit-2 von @ ed-heal vermieden. – Ravi

+0

@ravi: Langer Kommentar. Meine Antwort adressiert das Kernproblem des OP: Der Rückgabewert wird nicht verwendet. Aus dem Post ist nicht klar, dass der Baum ein binärer Suchbaum ist und dass die Suche auf nur einen Teilbaum beschränkt werden kann. Ohne diese Informationen habe ich meine Antwort auf den OP-Code modelliert. –

1

Nicht nur müssen Sie die Werte aus den rekursiven Aufrufen zurückzukehren, sollten Sie auch nur recurse in die Teile des Baumes, die Ihr search_item enthalten.

So vorausgesetzt, der Baum mit niedriger = sortiert bleibt dann funktionieren Sie sollten wie folgt aussehen:

int isElementInBinaryTree(BinaryTreeNode *root, int search_item) 
{ 
    if(root) { 
     if (search_item == root -> data) return 1; 
     else if (search_item < root -> data) return isElementInBinaryTree(root -> left, search_item); 
     else if (search_item > root -> data) return isElementInBinaryTree(root -> right, search_item); 
    } 

    return 0; 
} 
+0

Sie brauchen nicht 'if (search_item> root -> data) '. Oder das erste "else" sowie –

+0

Auch das zweite "else" wäre überflüssig –

+0

Sie schließen sich gegenseitig aus, aber die Strukturierung macht die Absicht sehr deutlich. – GrahamS