2017-04-19 21 views
-2

私は、ツリー内の要素を見つけると、ノードのパスを持つノードポインタの配列を返す関数path()を作成しようとしています。私は再帰を試みたが、何が間違っているのかわからない。関数パスには、Node *a、バイナリツリーint v、見つかる値、そしてint *pのような署名がある。ノードのmalloc配列を作成するsegmetationフォールト

はここに私のコードです:

typedef struct nodo { 
    int v; 
    struct nodo *left, *right; 
} Nodo; 

Nodo **path(Nodo *a, int v, int *p) { 
    (*p)++; 
    Nodo **r = NULL; 
    if (a == NULL) { 
    return NULL; 
    } 
    if (a->v == v) { 
    r = (Nodo**)malloc((*p)*sizeof(Nodo*)); 
    r[(*p)-1] = a; 
    return r; 
    } 

    else if (a->v < v) { 
    Nodo **r = path(a->right, v, p); 
    r[(*p)-1] = a; 
    return r; 
    } 
    else if (a->v > v) { 
    Nodo **r = path(a->left, v, p); 
    r[(*p)-1] = a; 
    return r; 
    } 
    return r; 
} 
+0

'a == NULL'かどうかをチェックする前に'(* p)++ 'をインクリメントしないでください。 –

+2

どのラインがクラッシュしますか? 'ram()'が 'path()'であると仮定していますか? –

+0

を見つけてください。あなたは実際に値を見つけたときにだけメモリを割り当てます。つまり、前のすべてのナビゲーションが 'path()'によって返された 'NULL'ポインタを参照します。私はあなたの最初のクラッシュだと思っています。 – zolid

答えて

1

あなたの元のコードの主な問題は、現在の深さを保持している場所は、すべての再帰の間で共有され、それが唯一のこれまでインクリメントされ、減らさないことのようです。以下のために、最初のコールは、深さ0を使用する必要が

typedef struct nodo { 
    int v; 
    struct nodo *left, *right; 
} Nodo; 

Nodo **path(Nodo *a, int v, int depth) { 
    Nodo **r; 
    if (a == NULL) { 
    return NULL; 
    } 
    if (a->v == v) { 
    r = malloc((depth+1)*sizeof(Nodo*)); 
    } 
    else if (a->v < v) { 
    r = path(a->right, v, depth+1); 
    } 
    else { 
    r = path(a->left, v, depth+1); 
    } 
    if (r != NULL) { 
    r[depth] = a; 
    } 
    return r; 
} 

:私はクリーンなアプローチは、以下のコードのようではなく、共有の深さ位置へのポインタとして、実際の数として深さを渡すことだと思います例:p = path(node, value, 0);

初期コールで0を通過することを避けるために、以下のように、関数の再帰部分が出因数分解することができる:

Nodo **path_(Nodo *a, int v, int depth) { 
    Nodo **r; 
    if (a == NULL) { 
    return NULL; 
    } 
    if (a->v == v) { 
    r = malloc((depth+1)*sizeof(Nodo*)); 
    } 
    else if (a->v < v) { 
    r = path_(a->right, v, depth+1); 
    } 
    else { 
    r = path_(a->left, v, depth+1); 
    } 
    if (r != NULL) { 
    r[depth] = a; 
    } 
    return r; 
} 

Nodo **path(Nodo *a, int v) { 
    return path_(a, v, 0); 
} 

そして最初のコールは、例えば:p = path(node, value);

+0

ありがとう、今私は理解する – zolid

関連する問題