【问题标题】:C - freeing memory of a binary tree using post-order traversalC - 使用后序遍历释放二叉树的内存
【发布时间】:2017-05-11 02:51:27
【问题描述】:

我想使用后序遍历删除二叉树。这意味着应该首先删除树的左侧部分,然后删除右侧的然后在随后的第二个函数中删除整个树并释放内存。我不能改变函数的参数,只能在里面玩:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "telefonbuch.h"

static inline bstree * create_node(unsigned long phone, char * name)
{
  bstree * newNode = (bstree *) malloc(sizeof(bstree));

  newNode->key.phone = phone;
  strcpy(newNode->key.name, name);
  newNode->left = NULL;
  newNode->right = NULL;

  return newNode;
}

void bst_insert_node(bstree * bst, unsigned long phone, char * name)
{
    if (bst == NULL)
    {
        return;
    }

    if (bst->key.phone > phone)
    {
        if (bst->left == NULL)
        {
            bst->left = create_node(phone, name);
            return;
        }

        bst_insert_node(bst->left, phone, name);
    }
    else
    {
        if (bst->right == NULL)
        {
            bst->right = create_node(phone, name);
            return;
        }

        bst_insert_node(bst->right, phone, name);

    }
}

bst_node * find_node(bstree* bst, unsigned long phone) {
  if (bst == NULL)
  {
      return NULL;
  }

  if(bst->key.phone > phone)
  {
      return find_node(bst->left, phone);
  }
  else if (bst->key.phone < phone)
  {
      return find_node(bst->right, phone);
  }

  return &(bst->key);
}

void bst_in_order_walk_node(bst_node* node) {
}

void bst_in_order_walk(bstree* bst) {
   int temp = 0;
   int level;

   while(temp < level)
   {
       printf("-");
       ++temp;
   }

   printf(" (%ld-%s)\n", bst->key.phone, bst->key.name);

   if (bst->left != NULL)
   {
      print_tree(bst->left, level + 1);
   }

   if (bst->right != NULL)
   {
      print_tree(bst->right, level + 1);
   }
}

void bst_free_subtree(bst_node* node) {

    …what goes here?…

}

void bst_free_tree(bstree* bst) {
  if(bst==NULL)
      return;
  bst_free_tree(bst->left);
  printf("Deleting %d node.\n",bst->key);
  free(bst);
  bst_free_tree(bst->right);
}  

以下是结构定义:

typedef struct _bst_node {
  char name[60];
  unsigned long phone;
} bst_node;

typedef struct _bstree {
  bst_node key;
  struct _bstree * left;
  struct _bstree * right;
  } bstree;

您能帮我完成/更正我的代码吗?

【问题讨论】:

  • 我不明白bst_free_subtree 应该做什么。它的参数是一个节点,所以你不能用它释放整个子树。顺便说一句,您的函数 bst_free_tree 部分错误,因为在释放 bst 之后使用了 bst-&gt;right。您必须在通话后 移动声明 free(bst)
  • 嘿 Ahmed,我也遇到了麻烦,你确定 free_subtree 的签名有效吗?您能否发布所有功能的所有签名?我可以为你解决这个问题:)
  • 在我看来,bst_free_tree 独自完成了整个工作。你需要bst_free_subtree 做什么? (如果 bstree 结构的定义包含 bst_node *key; 而不是 bst_node key;,情况会有所不同。)
  • 我发布了整个程序:)

标签: c algorithm recursion tree binary-search-tree


【解决方案1】:

你有:

void bst_free_tree(bstree* bst) {
  if(bst==NULL)
      return;
  bst_free_tree(bst->left);
  printf("Deleting %d node.\n",bst->key);
  free(bst);
  bst_free_tree(bst->right);
}

这会“按顺序”删除当前节点,并在释放后访问已释放的内存。不好!

你需要一个亲密的关系:

void bst_free_tree(bstree* bst)
{
    if (bst == NULL)
        return;
    bst_free_tree(bst->left);
    bst_free_tree(bst->right);
    printf("Deleting %d node.\n", bst->key);
    free(bst);
}  

这样遍历释放左子树,然后是右子树,最后释放当前节点。

我认为不需要bst_free_subtree() 函数; bst_free_tree() 函数同样可以很好地释放子树。

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-09
    • 1970-01-01
    • 2021-12-04
    • 1970-01-01
    相关资源
    最近更新 更多