2017-06-15 53 views
2

我用於打印樹的顯示函數似乎只打印第一個元素,而不是其他的。我不知道爲什麼我懷疑我沒有遞歸的插入函數可能是原因,但似乎無法理解它出錯的地方。任何有關如何糾正或代碼失敗的解釋都會有所幫助。謝謝。這棵樹顯示函數爲什麼只打印第一個元素?

#include <stdio.h> 
#include<stdlib.h> 

void insert(int data_add,struct tree *temp); 
void display(struct tree *temp); 

struct tree 
{ 
    int data; 
    struct tree *left; 
    struct tree *right; 
} *root = NULL; 

int main() 
{ 
    int data_add,n; 
    while(1) 
    { 

    printf("\n\n1.Add\n2.Display\n4.Exit\n"); 
    scanf("%d",&n); 
    switch(n) 
    { 
     case 1: printf("\nEnter the element to add "); 
       scanf("%d",&data_add); 
       insert(data_add,root); 
       break; 
     case 2: printf("The nos are: "); 
       display(root); 
       break; 

     /*case 3: printf("The nos are: "); 
       reversedisplay(root);*/ 
     case 4: exit(1); 
       break; 
     default: printf("\nChoose a appropriate option"); 
    } 
    } 
} 

void insert(int data,struct tree *temp) 
{ 
    struct tree *current; 
    current = (struct tree*) malloc(sizeof(struct tree)); 
    current->data = data; 

    if(root == NULL) 
    { 
    root = current; 
    current->left = NULL; 
    current->right = NULL; 
    } 
    else 
    { 
    while(temp!=NULL) 
    { 
     if(data<temp->data) 
     { 
     temp = temp->left; 
     } 
     else 
     { 
     temp = temp->right; 
     } 
    } 

    temp = current; 
    current->left = NULL; 
    current->right = NULL; 
    } 

} 


void display(struct tree *temp) 
{ 
    if(temp == NULL) 
    return; 

    display(temp->right); 
    display(temp->left); 

    printf("%d",temp->data); 
} 
+0

問題是,插入一個元素時,您不是將新插入的元素分配爲任何其他節點的左側或右側子元素。每次嘗試插入元素時,您只是在插入時遍歷樹,因爲新元素未添加到樹中。 –

+0

但我已經爲當前分配空間,然後在遍歷後,我將溫度分配給當前的權利?那麼這不會在樹中添加新的元素?那麼如何實現呢? –

+0

檢查我的答案。 –

回答

0

在你的代碼的問題是,當插入節點你是不是使得新插入的節點的任何節點的左或右的孩子,因爲它的新節點實際上不是在你的樹插入。 你的代碼中不如意的事情 -

temp = current; 
current->left = NULL; 
current->right = NULL; 

出來的循環後,temp爲NULL,現在current被分配到temp,但沒有辦法從任何其他節點到達新節點樹,因爲它不是樹中任何節點的左/右子節點。
這裏我提供正確的代碼插入功能 -

void insert(int data,struct tree *temp) 
{ 
    struct tree *current; 
    current = (struct tree*) malloc(sizeof(struct tree)); 
    current->data = data; 
    current->left = NULL; 
    current->right = NULL; 

    if(root == NULL) 
    { 
    root = current; 
    current->left = NULL; 
    current->right = NULL; 
    } 
    else 
    { 
     struct tree *par=temp; //par is used to keep track of node whose left 
          //or right child will be the new node. 
     while(temp!=NULL) 
     { 
     par=temp; 
     if(data<temp->data) 
     temp=temp->left; 
     else temp=temp->right; 
     } 
     // The below part is used to make the new node as left or right child 
     // of the appropriate node. 
     if(data<par->data) 
      par->left=current; 
     else 
     par->right=current; 
    } 

} 

而且,在你的display功能略有變化,改變你的printf聲明 -
printf("%d ",temp->data);。 在以前的版本中,所有的節點值都會被打印出來,沒有空格給人的印象是隻打印一個數字。

+0

只有一個問題,代碼工作的很好,我明白我的錯誤也理解變量par在那裏做了什麼,但是當par和temp是相同的東西時,如何在temp改變時仍然指向現有樹。當指針等於這樣的指針時,他們不是指向同一個地方,而是一個變化?我知道一個noob問題,但請澄清。 –

0

問題出在insert函數中。您從不將新節點鏈接到舊節點。您需要使用指針來保存右側或左側節點的地址。取而代之的是,你只複製本地temp變量中當前節點的地址。你的代碼應該是:

... 
    else 
    { 
    t = &temp; 
    while(*t!=NULL) 
    { 
     if(data<(*t)->data) 
     { 
     t = &(*t)->left; 
     } 
     else 
     { 
     t = &(*t)->right; 
     } 
    } 

    *t = current; // actually copy current in right of left of last node 
    current->left = NULL; 
    current->right = NULL; 
    } 

但是這還不是全部,爲了顯示順序的元素,你應該改變顯示器:

void display(struct tree *temp) 
{ 
    if(temp == NULL) 
    return; 

    display(temp->left);  // left side first 
    printf("%d",temp->data); // then current 
    display(temp->right);  // finally right side 
} 
0

的時候下面while循環終止,temp保證爲NULL。然後你在做temp = current這使得本地指針temp指向current。它不會做你想做的事。

while(temp!=NULL) 
{ 
    if(data < temp->data) 
     temp = temp->left; 
    else 
     temp = temp->right; 
} 
temp = current; 

將其修改爲如下所示。

while(true) 
{ 
    if(data <= temp->data) 
    { 
     if (temp->left == NULL){ 
      temp->left = current; 
      return; 
     } 
     else 
      temp = temp->left; 
    } 
    else 
    { 
     if (temp->right == NULL){ 
      temp->right = current; 
      return; 
     } 
     else 
      temp = temp->right; 
    } 
} 

建議

  • 正如你已經聲明root節點作爲全局變量,把它當作一種說法是多餘的。聲明temp作爲局部變量來遍歷。
相關問題