如何从二叉树中删除节点?

时间:2018-12-03 12:36:59

标签: c binary-tree nodes

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

          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);
}

1 个答案:

答案 0 :(得分:0)

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

我不认为要求整个功能还可以。因此,这里有一个主意:首先,找到要删除的节点。然后:

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

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

  • 其他(如果节点具有正确的子节点),请从右侧的子树中删除最小值,然后将其插入节点中。您可以执行此操作而无需删除实际节点(只是子树中的一个)。