【问题标题】:How to remove node from binary tree?如何从二叉树中删除节点?
【发布时间】:2019-05-04 18:17:18
【问题描述】:

我修改了一个给定节点的现有程序,它将创建一棵二叉树,计算树遍历,但我不完全知道如何删除节点。我需要的只是一个简单的函数,可以从树中删除节点。基本上,该函数应该删除节点。例如:

          50                            50
       /     \         delete(20)      /   \
      30      70       --------->    30     70 
     /  \    /  \                     \    /  \ 
   20   40  60   80                   40  60   80






      50                             60
   /     \         delete(50)      /   \
  40      70       --------->    40    70 
         /  \                            \ 
        60   80                           80

我的代码:

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

struct bin_tree {
int data;
struct bin_tree * right, * left;
};
typedef struct bin_tree node;

void insert(node ** tree, int val)
{
    node *temp = NULL;
    if(!(*tree))
    {
        temp = (node *)malloc(sizeof(node));
        temp->left = temp->right = NULL;
        temp->data = val;
        *tree = temp;
        return;
    }

    if(val < (*tree)->data)
    {
        insert(&(*tree)->left, val);
    }
    else if(val > (*tree)->data)
    {
        insert(&(*tree)->right, val);
    }

}

void print_preorder(node * tree)
{
    if (tree)
    {
        printf("%d\n",tree->data);
        print_preorder(tree->left);
        print_preorder(tree->right);
    }

}

void print_inorder(node * tree)
{
    if (tree)
    {
        print_inorder(tree->left);
        printf("%d\n",tree->data);
        print_inorder(tree->right);
    }
}

void print_postorder(node * tree)
{
    if (tree)
    {
        print_postorder(tree->left);
        print_postorder(tree->right);
        printf("%d\n",tree->data);
    }
}

void deltree(node * tree)
{
    if (tree)
    {
        deltree(tree->left);
        deltree(tree->right);
        free(tree);
    }
}

node* search(node ** tree, int val)
{
    if(!(*tree))
    {
        return NULL;
    }

    if(val < (*tree)->data)
    {
        search(&((*tree)->left), val);
    }
    else if(val > (*tree)->data)
    {
        search(&((*tree)->right), val);
    }
    else if(val == (*tree)->data)
    {
        return *tree;
    }
}

void main()
{
    node *root;
    node *tmp;
    //int i;

    root = NULL;
    /* Inserting nodes into tree */
    insert(&root, 9);
    insert(&root, 4);
    insert(&root, 15);
    insert(&root, 6);
    insert(&root, 12);
    insert(&root, 17);
    insert(&root, 2);
    insert(&root, 0);
    /* Printing nodes of tree */
    printf("Pre Order Display\n");
    print_preorder(root);

    printf("In Order Display\n");
    print_inorder(root);

    printf("Post Order Display\n");
    print_postorder(root);
    /* Search node into tree */
    tmp = search(&root, 4);
    if (tmp)
    {
        printf("Searched node=%d\n", tmp->data);
    }
    else
    {
        printf("Data Not found in tree.\n");
    }

    /* Deleting all nodes of tree */
    deltree(root);
}

【问题讨论】:

  • 我不认为要求整个函数是可以的。因此,这里有一个思路:首先,找到要移除的节点。如果节点没有子节点,只需将其删除。如果该节点有一个左孩子,找到它的最大值,从子树中删除它并替换那个最大值而不是给定的节点。否则(如果节点有右子节点),从右子树中删除最小值并将其插入到节点的位置。您可以在不删除实际节点的情况下执行此操作(仅删除子树中的节点)。
  • @nm_tp 感谢您的想法,我设法做到了。将其发布为答案,我会将其标记为已回答
  • @FrancescoBernouli 如果可以的话,你可以用你用来解决问题的代码来回答你自己的问题。我假设您使用了this exercise,它描述了要做什么。

标签: c binary-tree nodes


【解决方案1】:

我正在按照 OP 的要求复制评论。

我不认为要求整个函数是可以的。因此,这里有一个思路:首先,找到要移除的节点。那么:

  • 如果节点没有子节点,只需将其删除(释放其内存并将父节点的指针设置为 NULL)。

  • 如果节点有一个左孩子,找到它的最大值,从子树中删除它并替换那个最大值而不是给定的节点。

  • 否则(如果节点有右子节点),从右子树中删除最小值并将其插入到节点的位置。您可以在不删除实际节点(仅来自子树的节点)的情况下执行此操作。

【讨论】:

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