考研之二叉排序树BST

有一说一 王道的代码是真的垃圾,简单的装下懂,然后难得就不写了,买你的书是让我自己悟啊?

二叉排序树的删除 挺复杂的。直接改成文字叙述了,研究了好久 ,把代码整出来了。

废话不多说,上代码:

#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
	 
	
} 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值