算法思想:遍历二叉排序树,查找要删除结点x。将x结点看作子树的根。如果x结点不存在左右子树(即为叶子节点),直接将该节点空间释放,指针置为空;如果x结点只存在右子树,右孩子即为删除x结点后的根;如果x结点只存在左子树,左孩子即为删除子树后的根;如果x结点存在左右子树,则需要找到左子树中值最大的结点,与要删除结点进行值替换,此时又回到了前面两种情况,则进行递归。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char ElemType;
typedef struct BSTNode {
ElemType data;
struct BSTNode* lchild;
struct BSTNode* rchild;
}BSTNode, * BSTree;
//中序遍历
void inOrder(BSTree T) {
if (T != NULL) {
inOrder(T->lchild);
printf("%c", T->data);
inOrder(T->rchild);
}
}
//插入操作
void insertBSTree(BSTree& T, ElemType num) {
if (T == NULL) {
T = (BSTNode*)malloc(sizeof(BSTNode));
T->data = num;
T->lchild = NULL;
T->rchild = NULL;
}
else if (T->data < num) {
insertBSTree(T->rchild, num);
}
else if (T->data > num) {
insertBSTree(T->lchild, num);
}
}
//创建二叉排序树
BSTree creatBSTree() {
ElemType num;
BSTNode* T = NULL;
while (scanf("%c", &num) && num != '\n') {
insertBSTree(T, num);
}
return T;
}
void delect(BSTree& T, ElemType x);
void delectOperate(BSTree& T) {
//左右子树都为空
if (T->lchild == NULL && T->rchild == NULL) {
free(T);
T = NULL;
}
//只存在右子树
else if (T->lchild == NULL) {
BSTNode* pnode = T;
T = T->rchild;
free(pnode);
pnode = NULL;
}
//只存在左子树
else if (T->rchild == NULL) {
BSTNode* pnode = T;
T = T->lchild;
free(pnode);
pnode = NULL;
}
//左右子树都存在
//删除操作;找到左子树中值最大的结点,与要删除结点进行值替换
//此时又回到了前面两种情况,则进行递归
else {
BSTNode* pnode=T->lchild;
while (pnode->rchild != NULL) {
pnode = pnode->rchild;
}
T->data = pnode->data;
delect(T->lchild,pnode->data);
}
}
//查找要删除结点
void delect(BSTree& T, ElemType x) {
if (T != NULL) {
if (T->data == x) {
delectOperate(T);//进行删除操作
}
else if (T->data < x) {
delect(T->rchild, x);
}
else {
delect(T->lchild, x);
}
}
}
int main() {
BSTree T = creatBSTree();
inOrder(T);
printf("\n");
ElemType x;
scanf("%c", &x);//输入要删除元素
delect(T, x);
inOrder(T);
return 0;
}