释放二叉树C的内存

释放二叉树C的内存,c,free,binary-tree,C,Free,Binary Tree,我想从分配的二叉树中释放内存,什么样的遍历最适合这样做 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=elem

我想从分配的二叉树中释放内存,什么样的遍历最适合这样做

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

深度优先搜索最适合于此

请考虑不同的遍历类型的作用,并记住,释放内存后,将不再允许访问它:

  • 预订购:在访问任何儿童之前执行的操作
  • 顺序:访问左子树后、右子树前执行的操作
  • Postorder:访问所有子树后执行的操作
鉴于上述陈述,答案应该是明确的。

当你说“最佳”时,你是指“正确”(即,访问释放的内存不会导致混乱)还是“最有效”还是什么

就正确性而言:只要在释放数据后小心不要访问数据,就可以选择任何您喜欢的内容。显然最简单的方法(我不会明确说明,因为这看起来有点像家庭作业:-)但如果你想写尽可能少的代码,你会这么做[编辑添加:这是“cnicutar”发布的内容;我希望这毕竟不是家庭作业!])效果很好


通过适当匹配释放顺序和分配顺序,您可能会获得更有效的结果(在空间或时间上),但细节取决于内存分配器,您可能不必在意。

由于它是一棵树,您应该使用递归方法

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
检查seg故障和内存泄漏的一个很酷的方法是使用

valgrind--leak check=full./yourProgram

void deallocate (struct Node * p)
{
    if(p==NULL)
        return;

    deallocate(p->right);
    deallocate(p->left);

    free(p);
}
在这个函数中传递根,它将释放树使用的所有堆内存


如果您的树非常大,递归调用可能会导致堆栈溢出(ahhhhhh),在这种情况下,您可能希望采用不同的路径(迭代),尽管这会增加时间复杂性。我认为这没有什么区别,但我希望在释放
节点之前释放
数据。我不得不再三考虑你的代码,谢谢!这很好,但我有错误上下文“条件跳转或移动取决于未初始化的值”和“未初始化的值是由堆分配创建的”
void deallocate (struct Node * p)
{
    if(p==NULL)
        return;

    deallocate(p->right);
    deallocate(p->left);

    free(p);
}