2017-03-13 4 views
0

Ich habe eine Struktur namens Node, das erste Argument ist int, die anderen sind Knotenzeiger. Wenn ich root-> left drucken wollte, hat es nicht funktioniert, das Programm stoppte, wenn ich es ausführte. Ich weiß nicht, vielleicht mache ich ein wirklich komisches Ding, indem ich erwarte, dass es etwas zurückgibt, aber was ist das Problem?Binärbaum akzeptiert keinen neuen Knoten

+0

Wo stellen Sie einen Knoten in der Struktur auf "Temp" zeigen? – NathanOliver

+0

Nicht initialisierte lokale nicht statische Variablen (wie die, die Sie haben) haben einen * unbestimmten * Wert, bis Sie sie initialisieren. Die Verwendung dieser nicht initialisierten Variablen führt zu * undefiniertem Verhalten *. –

+3

Zeigen Sie auf die Zeile, wo Sie root-> left auf etwas anderes als Null setzen – pm100

Antwort

0

Schauen wir uns die Code Zeile für Zeile einen Blick:

struct Node { 
    int val; 
    Node* left; 
    Node* right; 
    Node* parent; 
    Node(int value, Node* left, Node* right, Node* parent): val(value), left(left), right(right), parent(parent){} 
}; 

void main() { 
    Node *root, *temp, *temp_before; 
    root = new Node(0, NULL, NULL, NULL); // root points to the newly allocated memory 
    temp_before = root; //temp_before also points to that memory 
    temp = temp_before->left; // temp points to the left of root, which is null 
    // NOTE: at this point, temp isn't connected to the tree, even if you allocate memory with it. 
    // You only have pointers ("handles") for those memory blocks but you haven't combined them together yet. 
    temp = new Node(5, NULL, NULL, NULL); // This allocated memory for the memory address pointed by temp 
    // temp = root->left; //error 
    root->left = temp; //correct one 
    // Now root->left points to the memory block you allocated with temp 
} 

Wenn Sie Speicher mit Zeigern, Ihre Zeiger verweist nur auf den Speicherblock zugewiesen werden. Sie werden nicht zu einer verbundenen Struktur, es sei denn, Sie verbinden sie manuell miteinander.

Das war, was Sie versucht haben, aber in der falschen Art und Weise. Stellen Sie es sich so vor: Wenn Sie Speicher reservieren, gibt Ihnen das Betriebssystem Speicherplatz aus dem Hauptspeicher. Es tut dies, indem Sie eine "Referenz" zu diesem Speicherblock geben, so dass Sie diesen Speicherblock verwenden können, wie Sie wollen. Deshalb werden Zeiger auch als "Handles" bezeichnet, da sie mit Speicherblöcken interagieren.

In der fehlerhaften Zeile überschreiben Sie den Zugriff auf den Speicher, den Sie gerade zugewiesen haben. Wenn Sie dies tun, verlieren Sie den Zugriff auf diesen Speicherblock bis zum Ende der Programmausführung. Diese Überschreibungen werden "Speicherlecks" genannt, weil dieser Speicherblock etwas ist, das Sie gefragt haben, aber vergessen haben.

Wenn Sie temp = root->left; ausführen, überschreibt er den Zeiger mit einem anderen Zeiger (in diesem Fall eine, die NULL Punkte) und wenn Sie versuchen, es zu drucken, gibt es Ihnen einen Fehler null pointer exception genannt, die aus dem Namen, den Sie klar kann Sehen Sie das Problem :)

Wenn Sie die Sache zu kompliziert machen, die Sie versuchen zu tun, passieren diese Fehler tendenziell passieren, vor allem, wenn Sie mit Speicher unerfahren sind. Die Art und Weise Sie den Code vereinfachen kann, ist:

void main() { 
    Node* root = new Node(0, NULL, NULL, NULL); // Allocate root 
    root->left = new Node(5, NULL, NULL, NULL); // This line means "add a new node to the left of my root" 

    std::cout << root->val << std::endl; 
    std::cout << root->left->val << std::endl; 
} 

Wenn Sie mit über die Umsetzung kämpfen, denken Sie daran, wie folgt aus:

Node* temp = new Node(5, NULL, NULL, NULL); 
root->left = temp; 

Dieser Code der gleiche wie der Code in main Funktion ist. Stellen Sie es sich so vor: Sie ordnen einen Speicherblock zu und greifen mit dem Handle temp darauf zu. Danach sind Sie , die die Information dieses Handle dem linken Knotenzeiger Ihres Stamms zuweist. Auf diese Weise können Sie über root->left auf denselben Speicherblock zugreifen, auch wenn Sie nicht mehr auf temp zugreifen können.

Der Code unten ist, wie Sie darüber nachgedacht haben. Versuchen Sie, über den Unterschied zwischen diesen beiden nachzudenken, und wenn Sie es herausgefunden haben, werden Zeiger mehr Sinn ergeben:

+1

aktualisiert Ich weiß, ich sollte nicht "Danke" in den Kommentaren am Stack-Überlauf schreiben, aber wirklich danke für diese weitreichende Antwort! Das war alles was ich suchte. Ich hatte Probleme mit Zeigern gleichzeitig und das half auch, und vielen Dank für Ihre Zeit, die Sie für die Antwort gegeben haben. –

0

Es gibt ein paar Dinge. Sie müssen überprüfen, ob Ihr Knoten gleich null ist. Sie sollten auch aktualisieren, was Sie ausgeben.

node = root; 
while (node != null) 
{ 
    count << node; 
    node = node->left; 

} 
+0

wenn node-> left gleich null ist, wie soll ich Knoten zu node-> left transportieren? –

+0

Knoten zunächst auf den Kopf setzen und dann durchfahren. Ich habe meine Antwort @ TahaSümer – Jay266

Verwandte Themen