二叉排序树的删除(附思路和源码C实例)

二叉排序树的删除

(一)、二叉排序树定义:详见《数据结构》(C语言版)严蔚敏,吴伟民 P.227 (9.2.1)

(二)、二叉排序树删除指定的target节点

  • a.若target为叶子节点,则直接删除target即可;
  • b.若target只有左子树(或者右子树),则将target的父节点和左子树(或者右子树)拼接,同时删除target即可;
  • c.若target同时拥有左子树和右子树,则将target的值和target的右子树中序遍历的第一个节点InorderFirstNodeOfTargetRight(即其右子树中的最小值)的值交换后,删除InorderFirstNodeOfTargetRight即可。
  • d(与c等价)若target同时拥有左子树和右子树,则将target的值和target的左子树中序遍历的最后一个节点InorderLastNodeOfTargetLeft(即其左边子树中的最大值)的值交换后,删除InorderLastNodeOfTargetLeft即可。

(三)、二叉排序树以(二)a,b,c,为准则进行二叉排序树指定节点的删除示例代码如下:

#include <stdio.h>
#include <stdlib.h>
#define DATATYPE int
#define STATUS int
#define FALSE 0
#define TRUE 1

/**
 * 二叉排序树结构体定义
 */
typedef struct BSTNode{
    DATATYPE data;
    struct BSTNode * lchild;
    struct BSTNode * rchild;
}BSTNode, *BSTree;

/**
 * 申请新的树节点内存空间
 * @return  BSTree 
 */
BSTree NewBSTNode(){
    BSTree node= (BSTree)malloc(sizeof(BSTNode));
    if (node == NULL){
        printf("OOM\n");
        exit(1);
    }
    return node;
}

/**
 * 将data数据渲染到新增节点,并且初始化新节点数据
 * @param data 
 * @return 
 */
BSTree GetAloneNode(DATATYPE data){
    BSTree newnode = NewBSTNode();
    newnode->lchild=NULL;
    newnode->rchild=NULL;
    newnode->data=data;
    return newnode;
}

/**
 * 二叉排序树的插入
 * @param bstroot 
 * @param data 
 * @return 
 */
BSTree InsertData(BSTree bstroot, DATATYPE data){
    BSTree newnode = GetAloneNode(data);
    if (bstroot==NULL){
        bstroot=newnode;
    } else if (data < bstroot->data){
        bstroot->lchild = InsertData(bstroot->lchild,data);
    }else if(data > bstroot->data){
        bstroot->rchild = InsertData(bstroot->rchild,data);
    }
    return bstroot;
}

/**
 * 递归查找
 * @return
 */
BSTree Search1(BSTree bstroot, DATATYPE data){
    if (bstroot==NULL){
        return NULL;
    }else if(data == bstroot->data){
        return bstroot;
    }else if(data < bstroot->data){
        return Search1(bstroot->lchild,data);
    }else if(data > bstroot ->data){
        return Search1(bstroot->rchild,data);
    }else{
        return NULL;
    }
}

/**
 * 非递归查找
 */
BSTree Search2(BSTree bstroot, DATATYPE data){
    BSTree tmp = bstroot;
    while (tmp){
        if (tmp->data == data){
            return tmp;
        }else if(tmp->data < data){
            tmp = tmp->rchild;
        }else if(tmp->data > data){
            tmp = tmp->lchild;
        }
    }
    return NULL;
}

/**
 *二叉排序树的前序遍历
 */
void Preorder(BSTree bsTree)
{
    if(bsTree == NULL)
        return;
    else
    {
        printf("%d ",bsTree->data);
        Preorder(bsTree->lchild);
        Preorder(bsTree->rchild);
    }
}

/**
 * 删除指定节点
 */
void DeleteNodeByData(BSTree bsTree, DATATYPE data){
    BSTree targetNode = Search2(bsTree,data);
    if (targetNode != NULL){

        BSTree q,s;
        if (targetNode->rchild == NULL){
            q = targetNode;
            targetNode = targetNode->lchild;
            free(q);
        }else if(targetNode->lchild == NULL){
            q = targetNode;
            targetNode = targetNode->rchild;
            free(q);
        }else{//左右子树均不为空,
            // 将其右子树中序遍历的第一个子女交换并且删除此子女
            // 或者将其左子树中序遍历的最后一个子女交换,并且删此子女
            q = targetNode;
            s = targetNode->rchild;
            //找到右子树中序遍历的第一个子女s,q为s的父节点
            while (s->lchild){
                q = s;
                s = s->lchild;
            }
            targetNode ->data = s->data;//交换数据
            if (q != targetNode){
                q->lchild = s->rchild;
            }else{
                q->rchild = s->rchild;
            }
            free(s);
        }
    }
}

int main() {
    DATATYPE a[10] ={17,7,21,4,11,18,25,3,6,19};
    BSTree bsTree = NULL;
    for (int i = 0; i < 10; ++i) {
        bsTree = InsertData(bsTree,a[i]);
    }
    Preorder(bsTree);
    printf("\n");
    DeleteNodeByData(bsTree,17);
    Preorder(bsTree);
    return 0;
}

(四)、欢迎讨论交流优化。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用C语言递归法求二叉搜索树的源代码: ```c #include <stdio.h> #include <stdlib.h> /* 定义二叉搜索树结构体节点 */ struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; /* 二叉搜索树插入操作 */ struct TreeNode* insert(struct TreeNode *root, int val) { if (root == NULL) { /* 如果树为空,则创建一个新节点 */ root = (struct TreeNode*) malloc(sizeof(struct TreeNode)); root->val = val; root->left = NULL; root->right = NULL; } else if (val < root->val) { /* 如果节点值小于根节点值,则递归插入子树中 */ root->left = insert(root->left, val); } else if (val > root->val) { /* 如果节点值大于根节点值,则递归插入右子树中 */ root->right = insert(root->right, val); } return root; } /* 中序遍历二叉搜索树 */ void inorderTraversal(struct TreeNode* root) { if (root != NULL) { inorderTraversal(root->left); /* 遍历子树 */ printf("%d ", root->val); /* 打印当前节点值 */ inorderTraversal(root->right); /* 遍历右子树 */ } } int main() { struct TreeNode *root = NULL; int arr[] = { 5, 2, 7, 1, 3, 6, 8 }; int n = sizeof(arr) / sizeof(arr[0]); /* 向二叉搜索树中逐个插入节点 */ for (int i = 0; i < n; i++) { root = insert(root, arr[i]); } /* 中序遍历二叉搜索树,输出所有节点值 */ printf("Inorder Traversal of BST:\n"); inorderTraversal(root); printf("\n"); return 0; } ``` 以上代码包括二叉搜索树的插入操作和中序遍历操作。在main函数中,创建一个空的二叉搜索树,然后向其中逐个插入数组中的元素。最后,打印所有节点的值,以中序遍历的方式输出。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值