删除二叉树元素

时间:2018-03-24 21:22:28

标签: c binary-tree

在此之前我可以运行它并且它可以工作但是实际上在sugegstions我已经更新了我的代码之后实际上在二叉树中添加了任何东西。

我更新了我的代码

但现在当我输入第一个学生时,确定。一旦我插入第二个学生,它就会崩溃。 并继续印刷。

已经存在无限次,我不知道为什么 帮助

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

typedef struct treenode
{
char name[50];
int id;
float mark[10];
struct treenode *left;
struct treenode *right;//binary tree 
} myTree;


void insert_student(myTree **root) {
   char name[50];
   myTree *temp = malloc(sizeof(myTree));
   printf("enter name of student: ");
   scanf("%s", name);
   printf("enter ID: ");
   scanf("%d", &temp->id);
   strcpy(temp->name,name);
   temp->left = NULL;
   temp->right = NULL;
   myTree *temp_root = *root;
   if(*root == NULL) {
      *root = temp;
   }
   else
   {
       while (temp_root != NULL)
     {
       if (strcmp(name, temp_root->name) == 0)
          {
           printf("Already exists\n");
           } 
       else if (strcmp(name, temp_root->name) > 0)
            {
           if(temp_root->right == NULL)
               {
                temp_root->right = temp;
               }
           temp_root = temp_root->right;
            } 
          else {
           if(temp_root->left == NULL)
                 {
                temp_root->left = temp;
                 }
           temp_root = temp_root->left;
               }
       }
   }
}


int main(){ 
 int option;
 int r=0;    

 myTree *root = malloc(sizeof(myTree));
 root = NULL;
 char nameholder[50];
 while (r != 1)
  {
    printf ("choose one of the following options\n");                                 
    printf ("1-Introduce new student\n");    
    printf ("2-Remove Student\n");
    printf ("3-Exit\n");
    scanf("%d",&option);                               
    myTree *temp,*ptr = malloc(sizeof(myTree));
    myTree *prev = malloc(sizeof(myTree)); 
    temp=root;
    switch(option)
       {
          case 1:                                           
                    insert_student(&root);      
          break;

         case 2:
          ptr=root;
          printf("Enter name of student you want to remove\n");
          scanf("%s", nameholder);
          while(ptr != NULL && strcmp(nameholder,ptr->name)==0)
             {
              prev=ptr;
              if(strcmp(nameholder,ptr->name)>0)                       
               {
               ptr = ptr->right;                                                    
               }
              if(strcmp(nameholder,ptr->name)<0)                         
                 {
                  ptr=ptr->left;                                               
                  }                                             
             }

               if(root == NULL) 
                 {
              printf("There is nothing in the tree\n");
                }
          else if(root != NULL){
          printf("Found the student you want to delete...\n");                                                     
          if ((ptr->left == NULL) && (ptr->right == NULL))
               {
               //if the node to delete is to the left of root
                  printf("DEBUG 1\n");
                    if (prev->left == ptr) 
                     { printf("DEBUG 2\n");
                       prev->left = NULL;
                       free(ptr);
  printf("It has been Deleted and the left is now connected to NULL\n");                 
                     }                                                      
        //if the node to delete is to the right of root
              else if (prev->right == ptr)
                 {
                 printf("DEBUG 4\n");
                 prev->right = NULL;
                 free(ptr); 
  printf("It has been Deleted and the right has been set to NULL\n");                   
                  }
         printf("DEBUG 5\n");
                         }           
      else if((ptr->left == NULL || ptr->right == NULL))
          {
          printf("This node has 1 child...\n");
           if(ptr->left != NULL)
             { printf("DEBUG 7\n");
               prev->left = ptr->left;
               free(ptr);
printf("Node has been Deleted and the previous node skips to the LEFT\n");
              } printf("DEBUG 8\n");
        if(ptr->right != NULL)
            { printf("DEBUG 9\n");
            prev->right = ptr->right;
           free(ptr);
printf("Node has been Deleted and the previous node skips to the RIGHT\n");
            }
        printf("DEBUG 10\n");
     }
         printf("DEBUG 11\n");
         if(ptr->left != NULL && ptr->right != NULL)
           {
           printf("This node has 2 children\n");
           }
           printf("DEBUG 12\n");                                          
 }                              
  break;

   case 3:
   r=1;
   break;

   default:
   printf("Not an option\n");
   r=1;
   break;


   }// end of switch - tree            


  }//end of infinite option loop - tree

 }//end of main 

也有人可以查看我的删除案例是不是错了?

1 个答案:

答案 0 :(得分:-1)

正如@sstefan所说,代码中存在许多问题,并且您认为插入工作正常并不正确。

解释行为。您正在添加新节点,但您并未将它们附加到树中。所以你所有的树都是根。 这是因为你首先达到NULL,然后为它分配一个节点,但你来的父母不知道这个节点。

一种方法是将该节点存储在prev指针中,并将新创建的节点附加到它。

其他方法是首先在临时节点中输入值,然后将其附加到正确的位置。

void insert_student(my_tree **root) {
       char name[50];
       my_tree *temp = malloc(sizeof(my_tree));
       printf("enter name of student: ");
       scanf("%s", name);
       printf("enter ID: ");
       scanf("%d", &temp->id);
       temp->name = name;
       temp->left = NULL;
       temp->right = NULL;
       my_tree *temp_root = *root;
       if(*root == NULL) {
          *root = temp;
       }
       else
       {
           while (temp_root != NULL) {
           if (strcmp(name, temp_root->name) == 0) {
               printf("Already exists\n");
               return;
           } else if (strcmp(name, temp_root->name) > 0) {
               if(temp_root->right == NULL) {
                    temp_root->right = temp;
               }
               temp_root = temp_root->right;
           } else {
               if(temp_root->left == NULL) {
                    temp_root->left = temp;
               }
               temp_root = temp_root->left;
           }
         }
       }
    }
}

我发现的第二个问题是你的while循环没有正确的条件,如果你找到的字符串不是root,它就不会进入循环。即使它是root用户,否则它只是一个无限循环。

现在解释一下调试语句,因为你的ptr始终指向从不拥有任何子节点的root,只有条件才能通过它们。