2017-09-22 49 views
2

正如標題所說,我試圖從具有2例樹中刪除一個節點:麻煩試圖消除從樹中的節點(結構)

  • 的節點是沒有連接到任何一個葉子
  • 節點連接到另一個節點

我能夠做出第二種情況下工作的功能(對我來說最困難的),但第一個(似乎容易)引起分段錯誤沒有不管我嘗試什麼。

這裏是結構的定義:

struct node { 
    int value; 
    struct node *sx; 
    struct node *dx; 
}; 

typedef struct node *tree; 

這裏是執行消除操作的模塊:

void destroy_node(tree Y, int elem) { 
    if (Y->value < elem) 
     destroy_node(Y->dx, elem); 
    if (Y->value > elem) 
     destroy_node(Y->sx, elem); 
    else { // 
     if (Y->sx == NULL && Y->dx == NULL) { 
      free(Y); <-- seg fault 
      Y = NULL; <-- seg fault 
     } 
     if (Y->sx != NULL && Y->dx == NULL) { 
      Y->value = (Y->sx)->value; 
      free(Y->sx); 
      Y->sx = NULL; 
     } 
     if (Y->sx == NULL && Y->dx != NULL) { 
      Y->value = (Y->dx)->value; 
      free(Y->dx); 
      Y->dx = NULL; 
     } 
     if (Y->sx != NULL && Y->dx != NULL) 
      printf("Can't eliminate that!\n"); 
    } 
    print_everything(Y); 
} 

這裏是main電話:

tree Y = T; 
printf("Which one you want to destroy? "); 
scanf("%d", &elem); 
destroy_node(Y, elem); 

要編譯函數我使用命令

gcc -std=gnu99 -Wall -Wextra c.c 

我的環境是虛擬機的Ubuntu 17.04與股票GCC

是構建樹

tree insert_node(tree T, int val) { 
    if (T == NULL) {  
     T = (tree)malloc(sizeof(struct node)); 
     T->value = val; 
     T->sx = NULL; 
     T->dx = NULL; 
    } else { 
     if ((T->value) < (val)) { 
      T->dx = insert_node(T->dx, val); 
     } 
     if ((T->value) > (val)) { 
      T->sx = insert_node(T->sx, val); 
     } 
    } 
    return T; 
} 

在這裏有主的通話EDIT 1

模塊此模塊

printf("How many nodes your tree will have? "); 
scanf("%d", &tot); 
for (int i = 0; i < tot; i++) { 
    printf("What is the %d° node? ", (i + 1)); 
    scanf("%d", &val); 
    T = insert_node(T, val); 
} 

P.S.如果有關於節目我會複製粘貼整個文件

+0

你可以添加你建樹的地方嗎? – atru

+0

@atru插入了您請求的其他函數,希望它有幫助 – Allen

+0

您忘記檢查'Y'是否爲空。 –

回答

0

有你的功能缺件的可理解性問題:

  • 你不檢查是否Y != NULL。你會在空樹上有未定義的行爲。
  • 第一個if聲明後還有一個缺失。如果Y->value <= elem錯誤地刪除節點。
  • 當您刪除節點時,您不會更新父指針。

您應該更改API返回的指針參數更新值:

tree destroy_node(tree Y, int elem) { 
    tree res = Y; 
    if (Y != NULL) { 
     if (Y->value < elem) { 
      Y->dx = destroy_node(Y->dx, elem); 
     } else 
     if (Y->value > elem) { 
      Y->sx = destroy_node(Y->sx, elem); 
     } else { 
     if (Y->dx == NULL) { 
      res = Y->sx; 
      free(Y); 
     } else 
     if (Y->sx == NULL) { 
      res = Y->dx; 
      free(Y); 
     } else { 
      printf("Can't eliminate that!\n"); 
     } 
    } 
    return res; 
} 

呼叫從main爲:

tree T; 
... 
printf("Which one you want to destroy? "); 
if (scanf("%d", &elem) == 1) 
    T = destroy_node(T, elem); 

當然,你必須找到一個解決方案,以刪除節點有2個分支。

+0

立即使用我的代碼。很明顯,我會找到一個解決方案來刪除具有2個分支的節點,但我通常嘗試從一個小代碼開始工作,然後添加新函數以避免太多混淆(和錯誤)。順便說一句,謝謝 – Allen

+0

@艾倫:這是一個很好的方法。重新讀取代碼,我意識到'if(Y-> sx == NULL && Y-> dx == NULL)'測試是多餘的。答覆更新和簡化。 – chqrlie