Как удалить узел из двоичного дерева? - PullRequest
0 голосов
/ 03 декабря 2018

Я изменил существующую программу, в которой заданы узлы, она создаст двоичное дерево, вычислит обходы дерева, но я не совсем знаю, как удалить узел.Все, что мне нужно, это простая функция, которая удаляет узел из дерева.По сути, функция должна удалить узел.Например:

          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 голосов
/ 03 декабря 2018

Я копирую комментарий в соответствии с запросом OP.

Я не верю, что запрос всей функции - это нормально.Поэтому вот идея: сначала найдите узел, который вы хотите удалить.Затем:

  • Если у узла нет дочерних элементов, просто удалите его (освободите его память и установите указатель родителя в NULL).

  • Еслиу узла есть левый потомок, найдите его максимум, удалите его из поддерева и замените этот максимум вместо данного узла.

  • В противном случае (если у узла есть правильный дочерний элемент), удалите минимум из правого поддерева и вставьте его вместо узла.Вы можете сделать это, не удаляя фактический узел (только один из поддерева).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...