【问题标题】:Deleting a node form a binary search tree in C在C中从二叉搜索树中删除一个节点
【发布时间】:2015-01-19 21:27:29
【问题描述】:

我正在尝试编写一个函数来从二叉搜索树中删除一个节点(任何节点)。出于某种原因,delete 函数会删除多个节点。这是一个递归函数,当涉及到递归时,我有些困惑。下面是我的代码,有人可以帮我找出问题所在。 提前致谢

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


typedef struct node *nodeP;
typedef struct StudentRoster *StudentRosterP;

struct node
{
    nodeP left;
    char name[30];
    int ID;
    nodeP right;            
};

struct StudentRoster
{
    nodeP root;
    int size;
};

//create a new student roster
StudentRosterP newStudentRoster()
{
    StudentRosterP new;
    new = NULL;
    new = malloc(sizeof(struct StudentRoster));
    if (new == NULL)
        {
            fprintf(stderr, "Error: Memory allocation for Student Roster failed\n");
            return NULL;
        }
    else
        {
            new->root = NULL;
            new->size = 0;
            return new;
        }   
}

//creates a new node to store student information
nodeP newNode(char *name, int ID)
{
    nodeP new;
    new = NULL;
    new = malloc(sizeof(struct node));
    if(new == NULL)
    {
        fprintf(stderr, "Memory allocation for the node failed.\n");
        return NULL;
    }
    else
    {
        new->left = NULL;
        new->right = NULL;
        new->ID = ID;
        strcpy(new->name, name);
        return new;
    }
}
//function to insert student. this is a helper function, recursive call

void insert(nodeP root, int ID, char * name)
{

     if (ID == root->ID)
     {
         printf("Duplicate IDs not allowed\n");
         return;
     }
     else {
           if(ID < root->ID)
            {
               if(root->left == NULL)
               {
                   root->left = newNode(name, ID);
               }
               else
               {
                root = root->left;
                insert(root, ID, name); 
               }
            }
            else 
            {
               if(root->right == NULL)
               {
                   root->right = newNode(name, ID);
               }
               else
               {
                    root = root->right;
                    insert(root, ID, name);
               }
            }
     }
}

//to insert new student
void insertStudentRoster(StudentRosterP roster, char * name, int ID)
{

     nodeP root = roster->root;     
        if(roster->root == NULL)     // its empty 
        {
             roster->root = newNode(name, ID);         
        }

        else {                
            if (ID == roster->root->ID)
            {
                printf("Duplicate IDs not allowed\n");
                return;
            }
            else
            {
                insert(roster->root, ID, name);
            }            
        }     
}

/*
 * Helper function for removeStudentRoster
 * finds a node to be deleted and returns its pointer
 */
nodeP findMin(nodeP node)
{
    while(node->left != NULL)
    {
        node = node->left;
    }
    return node;         
}

//removes the node to be deleted
//returns null pointer to the parent function
//This is where I am having problem

nodeP delete(nodeP root, int ID)
{
    if(root == NULL)
    {
        return root;
    }

    else if(ID < root->ID)
    {
        root->left = delete(root->left, ID);
    }
    else if(ID > root->ID)
    {
        root->right = delete(root->right, ID);
    }
    else
    {
        if (root->left == NULL && root->right == NULL)
        {

           free(root);
           root = NULL;
        }

        else if(root->left == NULL)
        {
            nodeP temp = root;
            root = root->right;
            free(temp);
        }
        else if(root->right == NULL)
        {
            nodeP temp = root;
            root = root->left;
            free(temp);
        }
        else
        {
            nodeP temp = findMin(root->right);
            root->ID = temp->ID;
            strcpy(root->name, temp->name);
            root->right = delete(root->right, temp->ID);

        }
        return root;
    }
}

/*
 * Removes the node containing the matching names
 * Parameters: StudentRoster, id
 */
void removeStudentRoster(StudentRosterP roster, int ID)
{
    if(roster == NULL)
    {
        printf("The Student roster does not exist\n");
        return;
    }
    else if(roster->root == NULL)
    {
        printf("The Student roster is empty\n");
        return;
    }
    else{
         //find the node to be deleted
        roster->root = delete(roster->root, ID);        
    }    
}

//for printing in ordered

void inOrder(nodeP node)
{
    if (node == NULL)
        return;
    inOrder(node->left);
    printf("ID #: %i, Name: %s \n", node->ID, node->name);
    inOrder(node->right);

}
/*
 * Displays all the entries in the Phone book in order
 * Display one person per line, ID followed by first name
 */

void displayStudentRoster(StudentRosterP roster)
{
   if (roster->root == NULL)    {
        printf("The Roster is empty");
        return;
    }
   else
    {
        inOrder(roster->root);
        return;        
    }    
}

int main()
{

    StudentRosterP newRoster;
    newRoster = newStudentRoster();
    insertStudentRoster(newRoster, "Alice", 10);
    insertStudentRoster(newRoster, "Jake", 8);

    insertStudentRoster(newRoster, "josh", 12);
    insertStudentRoster(newRoster, "Alen", 9);
    insertStudentRoster(newRoster, "Joe", 11);    


    removeStudentRoster(newRoster, 11);      //it removes the whole roster when removing a node  that has no childrens
//when removing the root, it also removes the right child

    displayStudentRoster(newRoster);



    return (EXIT_SUCCESS);
}

【问题讨论】:

    标签: c recursion data-structures binary-tree binary-search-tree


    【解决方案1】:

    在您的删除功能中,您的return 放错了位置(仅当IDroot-&gt;ID 匹配时才到达)。您需要将其移过下一个右大括号以将其放置在 else 之后:

            }
            /* "return root;" was here... */
        }
        return root; /* ..but should be here. */
    }
    

    此外,当ID 匹配时(最后一个else)删除节点的逻辑似乎是错误的。您需要做的是将右分支移动到左分支中最右边的节点,或者将左分支移动到右分支的最左边节点......然后返回该分支。因此,使用您的findMin() 找到右分支的最左侧部分,我们可以这样做:

            else
            {
                nodeP temp = findMin(root->right);
                temp->left = root->left;
                temp = root;
                root = root->right;
                free(temp);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多