2017-06-15 71 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作为局部变量来遍历。
相关问题