C和指针 第十七章 二叉树删除节点

二叉树的节点删除分为三种情况:

 1.删除的节点没有子节点,直接删除即可

 2. 删除的节点有一个子节点,直接用子节点替换既可以

 3.删除的节点有两个子节点。

对于第三种情况,一般是不删除这个节点,而是删除左子树中最大的值的节点,并用这个值替换原先应该被删除的节点。左子树的最大节点只可能有一个或者没有子节点,所以删除很方便。

//删除节点,返回指向修改过的节点的指针
TREE_NODE* deleteNode(TREE_TYPE value, TREE_NODE *tree)
{
    TREE_NODE *tempTree;
    if(tree == NULL){
        //未找到节点
        printf("no found value in tree
");
        return NULL;
    }else if(tree -> value > value){
        //如果要找的值在左子树中,到左子树中删除,删除节点后,返回节点指针给父节点,然后父节点修正自己的leftPtr或者rightPtr
        tree -> leftPtr = deleteNode(value, tree -> leftPtr);
    }else if(tree -> value < value){
        //如果在右子树中
        tree -> rightPtr = deleteNode(value, tree -> rightPtr);
    }else if(tree -> leftPtr && tree -> rightPtr){
        //找到该节点,且有双子树,先找最大左子树节点
        tempTree = findMaxNode(tree -> leftPtr);
        //替换值即可
        tree -> value = tempTree -> value;
        //然后删除该最大左子树节点,最大左子树只会有一个或者没有子节点,否则不会是最大子节点
        deleteNode(tree -> value, tempTree);
    }else{
        //如果没有子节点,或者有一个子节点,直接用子节点替换,然后删除
        //先保存最大右子树,然后将最大右子树用它的子节点替换,然后删除最大右子树
        tempTree = tree;
        if(tree -> leftPtr == NULL){
            tree = tree -> rightPtr;
        }else if(tree -> rightPtr == NULL){
            tree = tree -> leftPtr;
        }
        free(tempTree);
    }

    return tree;
}

测试代码:

#include <stdio.h>
#include "BinaryTree.h"

int main()
{
    createTree(20);
    insertNode(12);
    insertNode(5);
    insertNode(9);
    insertNode(16);
    insertNode(17);
    insertNode(25);
    insertNode(28);
    insertNode(26);
    insertNode(29);

    TREE_NODE *ptr;
    //删除节点5的父节点值12
    deleteNode(12, root);
    //再次查看5的父节点
    ptr = findParent(5);

    //如果为根节点,没有父节点
    if(ptr == NULL){
        printf("it's root");
    }else{
        printf("%d
", ptr -> value);
    }

    return 1;
}

运行:

12原本是5的父节点,删除后,从12的左子树中用最大左子树值9替换12,然后删除9,此时5的父节点变为9.

原文地址:https://www.cnblogs.com/yangxunwu1992/p/5880716.html