这是一个pta的题目,删除我没有用递归来写,写起来有些麻烦,但是总归是写出来了,查找函数我使用了嵌套,因为我还需要一个查找父节点的函数,所以直接封装了查找父节点的函数
需要提示的内容都在注释里了
/* 你的代码将被嵌在这里 */
//返回指定元素的父节点,返回空为根节点或者空树
Position FindPre(BinTree BST, ElementType X) {
BinTree T = BST;
BinTree pre = NULL;
while (T != NULL) {
//先判断是否相等
if (X == T->Data)
break;
pre = T;
if (X < T->Data) {
T = T->Left;
continue;
}
if (X > T->Data) {
T = T->Right;
continue;
}
}
return pre;
}
//返回一个节点
BinTree getNode(ElementType X) {
BinTree t = (struct TNode*)malloc(sizeof(struct TNode));
t->Data = X;
t->Left = NULL;
t->Right = NULL;
return t;
}
BinTree Insert(BinTree BST, ElementType X) {
//空树的情况
if (BST == NULL)
return getNode(X);
BinTree pre = FindPre(BST, X);// 返回要插入位置的父节点
//如果为空,表示当前树只有一个节点(则父节点就为根)
if (pre == NULL)
pre = BST;
//判断
if (X < pre->Data&&pre->Left == NULL) {
pre->Left = getNode(X);
}
if (X > pre->Data&&pre->Right == NULL) {
pre->Right = getNode(X);
}
return BST;
}
//删除元素,使用右子树的最小节点替代原来节点的位置
BinTree Delete(BinTree BST, ElementType X) {
//先查找到对应元素的节点
BinTree del = Find(BST,X);//要删除的节点
if (del == NULL) {
//找不到或者空树的情况都是x不在树中,可以一起讨论
printf("Not Found\n");
return BST;
}
BinTree delR = del->Right;//要删除的节点的右孩子
BinTree delL = del->Left;//要删除节点的左孩子
int isBase = 0;//判断要删除的元素是否为根节点
//判断是否为根节点
if (del == BST)
isBase = 1;
//右孩子不为空
if (delR != NULL ) {
//非根节点,则先断开其父节点的连接
BinTree father = FindPre(BST, X);
if (!isBase) {
if (X < father->Data)
father->Left = NULL;
else father->Right = NULL;
}
//找右子树的一个最小元素
BinTree minNum = FindMin(delR);
//如果最小元素为本身
if (minNum == delR) {
//要删除元素的父节点指向(如果非根节点)
if (!isBase) {
if (minNum->Data < father->Data)
father->Left = minNum;
else father->Right = minNum;
}
//最小节点指向要删除元素的左子树
minNum->Left = delL;
//释放资源
free(del);
//如果为根节点
if (isBase)
BST = minNum;
//父节点连接替代节点
else {
if (minNum->Data < father->Data)
father->Left = minNum;
else
father->Right = minNum;
}
return BST;
}
//最小元素为右孩子的最左元素
else {
//找到该最小元素的父节点,断开与最小元素的连接
BinTree minPre = FindPre(delR,minNum->Data);
minPre->Left = NULL;
//将最左元素的右孩子给其父节点的左指针
minPre->Left = minNum->Right;
//指向左右孩子
minNum->Left = delL;
minNum->Right = delR;
//如果为根节点
if (isBase)
BST = minNum;
//非根节点,父节点连接
else {
if (minNum->Data < father->Data)
father->Left = minNum;
else
father->Right = minNum;
}
//释放资源
free(del);
return BST;
}
}
//右孩子为空且左孩子不为空(找左孩子的最大节点)
else if (delR == NULL&&delL!=NULL) {
//获取最大值
BinTree maxNum = FindMax(delL);
BinTree father = FindPre(BST, X);//返回要删除元素的父节点
//断开非根节点的父节点的连接
if (!isBase) {
if (X < father->Data)
father->Left = NULL;
else father->Right = NULL;
}
//如果最大元素就是左孩子本身
if (maxNum == delL) {
//如果为根节点(此时不存在右子树)
if (isBase) {
//直接返回最大值节点
free(del);
return maxNum;
}
//非根节点
else {
if (maxNum->Data < father->Data)
father->Left = maxNum;
else father->Right = maxNum;
free(del);
return BST;
}
}
//最大元素非左孩子本身(左孩子的最右节点)
else {
//找到最大元素的父节点并断开连接
BinTree maxpre = FindPre(BST, maxNum->Data);
maxpre->Right = NULL;
//开始连接左右孩子
maxNum->Left = delL;
maxNum->Right = delR;
if (isBase)
BST = maxNum;
else {
//父节点连接
if (maxNum->Data < father->Data)
father->Left = maxNum;
else father->Right = maxNum;
}
free(del);
return BST;
}
}
//左右孩子都为空
else if (delR == NULL && delL == NULL) {
//先判断要删除的元素是否为根节点
if (del == BST) {
//等于根节点,直接释放
free(del);
return NULL;
}
//不等于根节点
else{
//找到该元素的父节点,并置空
BinTree p = FindPre(BST,X);
if (X < p->Data) {
p->Left = NULL;
}
else
{
p->Right = NULL;
}
//释放资源
free(del);
return BST;
}
}
return BST;
}
//搜索指定元素,返回这个元素的节点地址
Position Find(BinTree BST, ElementType X) {
BinTree T = FindPre(BST, X);
//为空,则为空数或根节点,直接返回
if (T == NULL) {
return BST;
}
if (X < T->Data)
return T->Left;
else
return T->Right;
}
Position FindMin(BinTree BST) {
if (BST == NULL)
return NULL;
//一直往左子树遍历
while (BST->Left!=NULL){
BST = BST->Left;
}
return BST;
}
Position FindMax(BinTree BST) {
if (BST == NULL)
return NULL;
while (BST->Right!=NULL){
BST = BST->Right;
}
return BST;
}
最后提交