2012-02-07 37 views
2

我想從我分配的二叉樹中釋放內存哪些遍歷最適合這樣做?釋放二叉樹的內存C

typedef struct Node{ 
struct Node * right; 
struct Node * left; 
void * data; 
}Node; 


typedef int (*cmp) (void*,void *); 


Node* init(void * element){ 
    Node * newNode=(Node*)malloc(sizeof(Node)); 
    newNode->data=element; 
    newNode->left=NULL; 
    newNode->right=NULL; 
    return newNode; 
} 

void insert(void * element, Node** root,cmp compareTo){ 
    if(*root==NULL){ 
     *root=init(element); 
     return; 
    } 
    if(compareTo(element,(*root)->data)==1) 
     insert(element,&((*root)->left),compareTo); 
    else 
     insert(element,&((*root)->right),compareTo); 
} 

回答

7

由於它是一棵樹,你應該採用遞歸方法。

deallocate (node): 
    //do nothing if passed a non-existent node 
    if node is null 
     return 

    //now onto the recursion 
    deallocate(left node) 
    deallocate(right node) 

    free node 
2

深度優先搜索是最適合這個

7

想想不同類型的遍歷做,並牢記,以後你可用內存你不能再訪問:

  • 預購:操作
  • 在順序訪問任何孩子之前進行的:在訪問左子樹後進行手術,右子樹前
  • Postord er:在訪問所有的子樹後進行的操作

鑑於上述說法,答案應該清楚。

1

當你說「最好」時,你的意思是「正確」(即不會導致通過訪問釋放的內存導致混亂)或「最有效」或什麼?

只要正確:只要你注意不要在釋放數據後訪問數據。顯而易見的最簡單的方法(我不會明確說明,因爲這看起來有點像家庭作業:-)但是如果你想盡可能少編寫代碼,你會怎麼做[編輯補充:這是'cnicutar'發佈的內容;畢竟我希望這不是作業!))工作得很好。

通過將釋放順序與分配順序進行適當匹配,您可能會獲得更高效的結果(空間或時間),但細節取決於您的內存分配器,您可能不應該在意。

1
void free_tree(Node * node){ 
    //post-order like FatalError hinted at 
     if (node != NULL) { 
     free_tree(node->right); 
     free(node->data); //if data was heap allocated, need to free it 
     free_tree(node->left); 
     free(node); 
    }} 

一個很酷的方式來檢查賽格故障和內存泄漏是使用

valgrind --leak-check=full ./yourProgram