有一说一 王道的代码是真的垃圾,简单的装下懂,然后难得就不写了,买你的书是让我自己悟啊?
二叉排序树的删除 挺复杂的。直接改成文字叙述了,研究了好久 ,把代码整出来了。
废话不多说,上代码:
#include<iostream>
#include<stdlib.h>
using namespace std;
struct BiTree{
int data;
struct BiTree *left,*right;
};
bool isleft = false;
struct BiTree *CreatBitree(struct BiTree *T,int x){
T = (struct BiTree *)malloc(sizeof(struct BiTree));
T->left = NULL;
T->right = NULL;
T->data = x;
return T;
}
bool Insert(struct BiTree *(&T),int x){
if(T==NULL) {
T = CreatBitree(T,x);
return true;
}
if(T->data == x) return false;//数据已经存在
else if(T->data>x) return Insert(T->left,x); //数据比T小 进入左子树
else return Insert(T->right,x);//同理 右子树
}
struct BiTree *Seach(struct BiTree *T,int x){
if(T==NULL) return NULL;
if(T->data == x) return T;
else if(T->data>x) Seach(T->left,x);
else Seach(T->right,x);
}
struct BiTree *searchParent(struct BiTree *T,struct BiTree *p){
if(T==NULL) return NULL;
if(T->left && T->left->data == p->data) {
isleft = true; return T;
}
if(T->right && T->right->data == p->data){
isleft = false; return T;
}
if(T->data > p->data) return searchParent(T->left,p);
if(T->data < p->data) return searchParent(T->right,p);
}
void Inordertree(struct BiTree *T){//中序遍历正好可以按顺序输出插入的数据
if(T==NULL) return ;
if(T->left) Inordertree(T->left);
printf("%d ",T->data);
if(T->right) Inordertree(T->right);
}
bool Delete(struct BiTree *(&T),int x){
/*
二叉排序树的删除
1、删除的是叶子节点
直接删除
2、删除的是只有一个子节点
叶子节点直接继承父节点位置
3、删除的节点有左右节点
以中序遍历的前驱和后继节点替换,下面的代码演示是以后继节点替换
*/
struct BiTree *parent=NULL;
struct BiTree *p = Seach(T,x);
if(T==NULL|| p == NULL) return false;
if(p==T) parent = NULL; //若只有根节点一个节点好比需要删除的时候; 直接free 就完了
else parent = searchParent(T,p);
if(p->left == NULL && p->right == NULL){//此人为孤儿
if(parent==NULL){//此时数据只有一个节为根节点 且要删除它。
T=NULL;
return true;
} else{//不是根节点
if(isleft) parent->left = NULL;
else parent->right = NULL;
}
}
else if(p->left&&p->right){//要删除的节点儿女双全,既有左子树又有右子树,需要选一个合适的节点继承,这里使用右子树中最左节点
if(parent){
struct BiTree *temp = p;
p=p->right;//右子树
if(p->left == NULL){//如果p只有右子树
p->left = temp->left;
if(isleft) parent->left = p;
else parent->right->data = p->data;
}
while(p->left) {//最左节点
temp = p;
p=p->left;
}
if(isleft) parent->left->data = p->data;
else parent->right->data = p->data;
temp->left= NULL;
}else{
struct BiTree *temp = T;
p=p->right;//右子树
if(p->left == NULL){//如果p只有右子树
if(isleft) {
T->data = p->data;
T->left = NULL;
}
else{
T->data = p->data;
T->right = NULL;
}
} else{
while(p->left) {//最左节点
temp = p;
p=p->left;
}
T->data = p->data;
temp->left = NULL;
}
}
}else if(p->left&&p->right==NULL){//第二种情况有左子树
if(parent==NULL) {
T = p->left;
}
else{
if(isleft) parent->left=p->left;
else parent->right=p->left;
}
}else{//只有右子树
if(parent==NULL) {
T = p->right;
}
else{
if(isleft) parent->left=p->right;
else parent->right=p->right;
}
}
return true;
}
int main(){
struct BiTree *T=NULL;
int n;cin>>n;
for(int i=0;i<n;i++){
int x;scanf("%d",&x);
if(!Insert(T,x)){
printf("此数据已经存在\n");
}
}
for(int i=0;i<n;i++){//搜索数据n此 不想罗嗦了 就跟输入用的同一个数据
int x;cin>>x;
if(!Seach(T,x)){
printf("查找没有此数据\n");
}
}
for(int i=0;i<10;i++){//删除数据2俩
Inordertree(T);
printf("\n");
int x;cin>>x;
if(!Delete(T,x)){
printf("查找没有此数据\n");
}
}
// 14
// 6 3 11 1 5 8 13 2 4 7 9 12 15 14
}