五:二叉排序树的初始化操作及应用

树形结构:二叉排序树(、链表)

查找的非递归算法

Status BSTSearch(BiTree bt, KeyType K,
			    BiTree &p, BiTree &f){
  //在根为bt的二叉排序树上查找键值等于K的记录
  //查找成功,用指针p指向目标;f指向目标的双亲,f初值为NULL
	p=bt;
	while(p){
	   if(K<p->key){f=p;p=p->lchild;} //左子树上继续找
		else if(K>p->key)
			   {f=p; p=p->rchild;} //右子树上继续找
		         else return TRUE; //查找成功
	}//end while
	return  FALSE;    //查找失败
}

二叉排序树的生成

void CreateBST (BiTree &bt){
	bt=NULL;
	for(scanf(R); R.key!=endmark; scanf(R)){
     f=NULL;
		if(!SearchBST (bt,R.key,p,f)){ //未找到R.key
		   S=new BiNode;
		   S->key=R.key; S->other=R.other;
		   S->lchild=S->rchild=NULL;
		   if(!f) bt=S;   //二叉排序树中的第一个结点
		   else if(S->key<f->key) f->lchild=S;
		   else  f->rchild=S;
		}//end if
		else printf("该结点已经存在!\n");
	}//for
}//end CreateBST

二叉排序树的删除操作

P的度为0

F->lchild=NULL;
F->rchild=NULL;

P的度=1 :将P的唯一的孩子交给双亲

F->lchild=P->lchild;
F->lchild=P->rchild;

P的度=2:两种删除方法

s=p->lchild;
while(s->rchild)s=s->rchild; //找P的中序前驱S
s->rchild=p->rchild;         //P的右孩子交给S
F->lchild=p->lchild;         //P的左孩子交给F
free(p);


void DeleteBST ( BiTree  &bt,  KeyType  K) { //删除bt上键值等于K的结点
	f=NULL;
	if(!SearchBST(bt,K,f,p)) return;//被删结点不存在
	if(p->lchild&&p->rchild){  //被删结点p的度为2—-方法2
		q=p; s=p->lchild;
		while(s->rchild){q=s; s=s->rchild;} //找s
		p->data=s->data;  //用s的值替换p的值
     if(q!=p) q->rchild=s->lchild; else q->lchild=s->lchild;
     delete s;  //释放s
	}//if
  else{  //被删结点p的度为1,0
		q = p->rchild ? p->rchild : p->lchild;//q指向p的孩子
		if(!f) T=q; //被删结点p是树根,重新指定树根
      else if(p==f->lchild)f->lchild=q; else f->rchild=q;
		delete p; //释放被删结点p
	}//else
}


课本

int Delete(BiTree &p){
    if(!p->rchild){  //右子树为空,则只需要重连它的左子树
        q=p;
        p=p->lchild;
        free(q);
    }
    else if(!p->lchild){ //左子树为空,则只需要重连它的右子树
        q=p;
        p=p->rchild;
        free(q);
    }
    else{ //左右子树均不为空
        q=p;
        s=p->lchild;
        while(s->rchild){q=s; s=s->rchild;}
        p->data=s->data;
        if(q!=p) q->rchild=s->lchild;
        else q->lchild=s->lchild;
        delete s;
        
    }
    return TRUE;
}

整体

#include<bits/stdc++.h>
using namespace std;

typedef struct BiTNode{
    int key;
    struct BiTNode *rchild,*lchild;
}BiTNode,*BiTree;

int SearchBST(BiTree bt, int K,BiTree &p, BiTree &f){
  //在根为bt的二叉排序树上查找键值等于K的记录
  //查找成功,用指针p指向目标;f指向目标的双亲,f初值为NULL
	p=bt;
	while(p){
	   if(K<p->key){f=p;p=p->lchild;} //左子树上继续找
		else if(K>p->key){f=p; p=p->rchild;} //右子树上继续找
        else return 1; //查找成功
	}//end while
	return  0;    //查找失败
}

void CreateBST (BiTree &bt){
	bt=NULL;
	int ch;
	cout<<"请输入结点值:"<<endl;
	cin>>ch;
	while(ch!=0){
          BiTree  f=NULL;
        BiTree p=new BiTNode;
		if(!SearchBST (bt,ch,p,f)){ //未找到R.key
		 BiTree  S=new BiTNode;
		   S->key=ch;
		   S->lchild=S->rchild=NULL;
		   if(!f) bt=S;   //二叉排序树中的第一个结点
		   else if(S->key<f->key) f->lchild=S;
		   else  f->rchild=S;
		}//end if
		else printf("该结点已经存在!\n");
		cout<<"请输入结点值:"<<endl;
        cin>>ch;
	}//for
}//end CreateBST

// 再来一个中序遍历进行输出
void Prit(BiTree T){
    if(T==NULL) return;
    Prit(T->lchild);
    cout<<T->key<<"-";
    Prit(T->rchild);
}
//void DeleZ(BiTree & T,int n){
//    BiTree p=new BiTNode;
//    BiTree f=new BiTNode;
//    SearchBST(T,n,p,f);
//    if(f->rchild==p){
//        f->rchild=NULL;
//        free(p);
//    }else{
//        f->lchild=NULL;
//        free(p);
//    }
//}
//
//void DeleT(BiTree &T, int n){
//        BiTree p=new BiTNode;
//    BiTree f=new BiTNode;
//    SearchBST(T,n,p,f);
//    if(f->rchild==p){
//        if(p->rchild) f->rchild=p->rchild;
//        else f->rchild=p->lchild;
//        free(p);
//    }
//    else{
//         if(p->rchild) f->lchild=p->rchild;
//        else f->lchild=p->lchild;
//        free(p);
//    }
//}
void DeleTh(BiTree &T, int n){
    BiTree p=new BiTNode;
    BiTree f=new BiTNode;
    SearchBST(T,n,p,f);
    if(!p->rchild&&!p->lchild){
        if(f->rchild==p){
        f->rchild=NULL;
        free(p);
    }else{
        f->lchild=NULL;
        free(p);
    }
    }
    if((p->rchild&&!p->lchild)  || (!p->rchild&&p->lchild)){
            if(f->rchild==p){
        if(p->rchild) f->rchild=p->rchild;
        else f->rchild=p->lchild;
        free(p);
    }
    else{
         if(p->rchild) f->lchild=p->rchild;
        else f->lchild=p->lchild;
        free(p);
    }
    }

    if(p->rchild&&p->lchild){
    BiTree q=p;
    BiTree s=p->lchild;
    while(s->rchild){
            q=s; s=s->rchild;
    } //找s
    // 这里之后就是s是最右边的,q是s的父结点
    p->key=s->key;  //用s的值替换p的值
     if(q!=p) {
            q->rchild=s->lchild;
     }else {
         q->lchild=s->lchild;}
     free(s); //释放s
    }
}
int main()
{
    BiTree bt;
    CreateBST(bt);
    //DeleZ(bt,21);
    //DeleT(bt,17);
    //DeleT(bt,25);
    int n;
    cout<<"请输入 你想要删除的结点:"<<endl;
    cin>>n;
    DeleTh(bt,n);
    Prit(bt);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值