2016-12-26 10 views
1

は、ポストオーダートラバーサルを使用してバイナリツリーを削除します。ツリーの左部分を最初に削除し、次に右部分を削除することを意味します。ツリー全体を削除し、その後に続く2番目の機能でメモリを解放します。私は、関数の引数を変更することは許されないことだし、それだけの内部で遊ぶことができます:ここでC - ポストオーダートラバーサルを使用するバイナリツリーのメモリを解放する

#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; 

あなたは仕上げ/が私を修正し、私を助けてもらえコード?

+0

'bst_free_subtree'が何をするのか分かりません。引数はノードなので、それを使ってサブツリー全体を解放することはできません。 BTst関数 'bst_free_tree'は部分的に間違っています。なぜなら、' bst-> right'は 'bst'が解放された後に使われるからです。あなたはあなたの呼び出しの後に 'free(bst)'ステートメントを移動させる必要があります。 – md5

+0

こんにちはAhmedさん、私もこれに問題があります。あなたはfree_subtreeの署名が有効であることを確信していますか?すべての機能のためにすべての署名を投稿できますか?私はあなたのためにこれを解決することができるでしょう:) – DrPrItay

+1

'bst_free_tree'は、仕事全体をちゃんとうまくできているようです。 'bst_free_subtree'には何が必要ですか? ( 'bstree'構造体の定義に' bst_node key; 'の代わりに' bst_node * key; 'が含まれていれば、その話は変わります) –

答えて

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()関数はサブツリーを均等に解放します。

関連する問題