Löschen Ich habe eine Funktion implementiert, die den Baumknoten zusammen mit seinen Unterstrukturen wie diese löscht:C Endlosschleife nach Binärbaum
void DeleteTree(BTreeNode * bt){
if(bt == NULL)
return;
DeleteTree(bt->left);
DeleteTree(bt->right);
printf("del tree data: %d \n", bt->data);
free(bt);
}
Und dann habe ich eine andere Funktion, die den Baum durchquert:
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action){
if(bt == NULL)
return;
action(bt->data);
PreorderTraverse(bt->left, action);
PreorderTraverse(bt->right, action);
}
Hier ist der Parameter "action" ein Funktionszeiger, der die Daten des Knotens als Argument verwendet und void return type hat, um eine andere Funktion aufzurufen, die die Daten des Knotens ausgibt.
Hier ist meine Haupt:
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
void ShowIntData(int data){
printf("%d ", data);
}
int main(){
BTreeNode * bt1 = MakeBTreeNode();
BTreeNode * bt2 = MakeBTreeNode();
BTreeNode * bt3 = MakeBTreeNode();
BTreeNode * bt4 = MakeBTreeNode();
BTreeNode * bt5 = MakeBTreeNode();
BTreeNode * bt6 = MakeBTreeNode();
SetData(bt1, 1);
SetData(bt2, 2);
SetData(bt3, 3);
SetData(bt4, 4);
SetData(bt5, 5);
SetData(bt6, 6);
MakeLeftSubTree(bt1, bt2);
MakeRightSubTree(bt1, bt3);
MakeLeftSubTree(bt2, bt4);
MakeRightSubTree(bt2, bt5);
MakeRightSubTree(bt3, bt6);
PreorderTraverse(bt1, ShowIntData);
printf("\n");
DeleteTree(bt3);
PreorderTraverse(bt1, ShowIntData);
return 0;
}
Das Problem ist, nach DeleteTree, wenn PreorderTraverse erneut aufgerufen wird, wird das Programm in eine Endlosschleife fällt, einige Werte Müll ausdrucken. Kannst du mir bitte erklären, warum es passiert? Zu Ihrer Information, ich zeige Ihnen BinaryTree.h und BinaryTree.c unten für Ihre Referenz.
BinaryTree.h
#ifndef __BINARY_TREE_H__
#define __BINARY_TREE_H__
typedef int BTData;
typedef struct _bTreeNode{
BTData data;
struct _bTreeNode * left;
struct _bTreeNode * right;
} BTreeNode;
BTreeNode * MakeBTreeNode(void);
BTData GetData(BTreeNode * bt);
void SetData(BTreeNode * bt, BTData data);
BTreeNode * GetLeftSubTree(BTreeNode * bt);
BTreeNode * GetRightSubTree(BTreeNode * bt);
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub);
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub);
typedef void VisitFuncPtr(BTData data);
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void InorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void PostorderTraverse(BTreeNode * bt, VisitFuncPtr action);
void DeleteTree(BTreeNode * bt);
#endif // __BINARY_TREE_H__
BinaryTree.c
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
BTreeNode * MakeBTreeNode(void){
BTreeNode * nd = (BTreeNode*)malloc(sizeof(BTreeNode));
nd->left = NULL;
nd->right = NULL;
return nd;
}
BTData GetData(BTreeNode * bt){
return bt->data;
}
void SetData(BTreeNode * bt, BTData data){
bt->data = data;
}
BTreeNode * GetLeftSubTree(BTreeNode * bt){
return bt->left;
}
BTreeNode * GetRightSubTree(BTreeNode * bt){
return bt->right;
}
void MakeLeftSubTree(BTreeNode * main, BTreeNode * sub){
if(main->left != NULL)
free(main->left);
main->left = sub;
}
void MakeRightSubTree(BTreeNode * main, BTreeNode * sub){
if(main->right != NULL)
(main->right);
main->right = sub;
}
void PreorderTraverse(BTreeNode * bt, VisitFuncPtr action){
if(bt == NULL)
return;
action(bt->data);
PreorderTraverse(bt->left, action);
PreorderTraverse(bt->right, action);
}
void DeleteTree(BTreeNode * bt){
if(bt == NULL)
return;
DeleteTree(bt->left);
DeleteTree(bt->right);
printf("del tree data: %d \n", bt->data);
free(bt);
}
Thank you very much.
Zeit zu lernen, wie ein Debugger verwenden .... – LPs
Ich benutze den Debugger und es sagt der Fehler passiert bei der Funktion ShowIntData, aber wenn der Speicher für den Baum Knoten freigegeben ist, sollte der Parameter bt in PreorderTraverse gleich NULL sein und f entkommen Salbung? – Ned
Siehe meine Antwort. free setzt den übergebenen Zeiger nicht automatisch auf 'NULL'. Sie sollten es mit Ihrem Debugger sehen. – LPs