C++和数据结构的新手试炼,删除函数写的非常冗杂,望大神多多指教~
#include <iostream>
#define ElemType int
using namespace std;
//二叉树结构体
typedef struct tree {
ElemType data;
struct tree* lchild, * rchild;
}*BiTree, BTNode;
//二叉排序树插入新节点
int BST_Insert(BiTree& T, ElemType x) { //这里引用指针T,不然本函数需返回指针
if (T == NULL) { //新建节点
T = (BiTree)malloc(sizeof(BTNode));
T->data = x;
T->lchild = T->rchild = NULL;
return 1;
}
else if (x == T->data)
return 0;
else if (x < T->data)
return BST_Insert(T->lchild, x);
else
return BST_Insert(T->rchild, x);
}
//查找关键字为x的节点,并返回指针
BTNode* BST_Search(BiTree T, ElemType x, BTNode*& p) {
p = NULL; //指针p用来指向被查找节点的双亲,便于插入或删除操作。
//若所查找结点为根节点,则p=NULL
while (x != T->data && T != NULL) {
p = T;
if (x < T->data)
T = T->lchild;
else
T = T->rchild;
}
return T;
}
//删除二叉树中值为x的个节点
void BST_Delete(BiTree& T, ElemType x) {
BTNode* p = (BTNode*)malloc(sizeof(BTNode)); //指针p用来指向被查找节点的双亲
BTNode* q = BST_Search(T, x, p); //查找关键字为x的节点,并返回指针
if (p != NULL) { //要删除节点不是根节点,存在双亲结点
if (q->lchild == NULL && q->rchild == NULL) { //叶节点
if (p->lchild == q)
p->lchild = NULL;
else
p->rchild = NULL;
free(q);
}
else if (q->lchild == NULL && q->rchild != NULL) { //有右孩子节点
if (p->lchild == q)
p->lchild = q->rchild;
else
p->rchild = q->rchild;
free(q);
}
else if (q->lchild != NULL && q->rchild == NULL) { //有左孩子节点
if (p->lchild == q)
p->lchild = q->lchild;
else
p->rchild = q->lchild;
free(q);
}
else { //左右孩子节点都存在,用直接后继代替要删除的节点
//直接后继就是右子树的最左的孩子节点
BTNode* r = q->rchild;
p = q;
while (r->lchild) {
p = r;
r = r->lchild;
}
q->data = r->data;
if (p == q) { //q的直接后继就是自己的右孩子
q->rchild = r->rchild;
free(r);
}
else { //q的直接后继是右子树的最左的孩子节点
p->lchild = NULL;
free(r);
}
}
}
else { //要删除的是根节点
if (q->lchild == NULL && q->rchild == NULL) { //根节点又是叶节点,树只有一个节点
T = NULL;
free(q);
}
else if (q->lchild == NULL && q->rchild != NULL) { //有右孩子节点,右孩子成为根节点
T = q->rchild;
free(q);
}
else if (q->lchild != NULL && q->rchild == NULL) { //有左孩子节点,左孩子成为根节点
T = q->lchild;
free(q);
}
else { //左右孩子节点都存在,用直接后继代替要删除的节点
//直接后继就是右子树的最底层左孩子节点
BTNode* r = q->rchild;
p = q;
while (r->lchild) {
p = r;
r = r->lchild;
}
q->data = r->data;
if (p == q) { //q的直接后继就是自己的右孩子
q->rchild = r->rchild;
free(r);
}
else { //q的直接后继是右子树的最左的孩子节点
p->lchild = NULL;
free(r);
}
}
}
cout << "删除成功" << endl;
}
//用n个数的关键字数组建立一个二叉排序树
void BST_Creat(BiTree& T, ElemType str[], int n) {
T = NULL;
for (int i = 0; i < n; i++) {
BST_Insert(T, str[i]);
}
}
//访问函数
void visit(BiTree T) {
cout << T->data << " ";
return;
}
//递归中序遍历
void InOrder(BiTree T) {
if (T) {
InOrder(T->lchild);
visit(T);
InOrder(T->rchild);
}
}