2017-04-19 60 views
-2

我試圖創建一個函數path(),它將返回一個節點指針數組與節點的路徑,當在樹中查找一個元素。我試圖用遞歸做,但不知道什麼是錯,函數路徑有一個簽名:Node *a,二叉樹,int v,找到的值,和int *p一樣,作爲訪問節點的計數器。分段錯誤創建malloc數組的節點

這裏是我的代碼:

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

哪一行會崩潰?運行它在調試器中找出 –

+0

當代碼範圍'r [(* p)-1] = a'在'malloc'之後調用 – zolid

回答

1

與原代碼的主要問題似乎是抱着當前深度的位置在所有的遞歸之間共享,它只會被遞增,遞減從來沒有。我認爲一個清潔器的方法是將深度通過作爲實際數目,而不是作爲一個指針到共享深度位置比,如在下面的代碼:

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

初始呼叫應當針對深度使用0,對於例如: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