二叉排序树
#include <iostream>
using namespace std;
typedef int ElementType;
struct BstNode
{
ElementType data;
BstNode *lch;
BstNode *rch;
};
class BstTree
{
public:
BstNode *root;
public:
BstTree(){root=NULL;}
void creat();
void NorecCreat(); //非递归创建二叉排序树
void inorder(){inorder(root);}
void deleteNode(BstNode *rt,BstNode *p,BstNode *par)//rt指向根结点,p指向被删除结点,par指向p的双亲
{ //删除后仍是二叉排序树
int is=1;
BstNode *s,*q; //s,q分别指向替代结点及其双亲,在同时有左右孩子的情况下,不需用到p的双亲par结点
if(p->lch==NULL)s=p->rch; //若p结点无左孩子,则让p的右孩子上移替代p结点,
else if(p->rch==NULL)s=p->lch; //若p结点无右孩子,则让p的左孩子上移替代p结点,(这里不用担心它的左孩子也为NULL的情况
else{ //因为若左孩子也为NULL,则s=p->lch;使得替代结点s=NULL;这正是无左右孩子的结果)
q=p;s=p->rch; //若有左右孩子,则用后继结点s替代p结点,结点s就是p右子树中数据域值最小(左)的结点
while(s->lch!=NULL) //所以先让p结点取s结点的值,再删除s结点(s一定没有左孩子,所以让s的右孩子上移替代s结点)
{q=s;s=s->lch;} //查找p结点右子树的最左结点
if(q==p) //p结点右子树没有左孩子
q->rch=s->rch;
else q->lch=s->rch;
p->data=s->data;
delete s;is=0; //这里要删除的是s结点
}
if(is) //p不是有左右孩子的情况
{
if(par==NULL)rt=s; //双亲结点f==NULL即是要删除的p结点就是根结点,在根结点左右孩子有一个或以上为空的情况下,根结点要改变
else if(par->lch==p)par->lch=s;
else par->rch=s;
delete p; //这里要删除的是p结点
}
}
private:
void inorder(BstNode *rt)
{
if(rt!=NULL){
inorder(rt->lch);
cout<<rt->data<<' ';
inorder(rt->rch);
}
}
BstNode* insertNode(BstNode *rt,BstNode *s);
};
void BstTree::creat()
{
BstNode *s;int i,n;ElementType k;
cout<<"n=?";cin>>n;
for(i=1;i<=n;i++)
{
cin>>k;
s=new BstNode;
s->data=k;
s->lch=s->rch=NULL;
root=insertNode(root,s);
}
}
void BstTree::NorecCreat()
{
BstNode *s;int i,n;ElementType k;
cout<<"n=?";cin>>n;
for(i=1;i<=n;i++)
{
cin>>k;
s=new BstNode;
s->data=k;
s->lch=s->rch=NULL;
if(root==NULL)root=s;
else {
BstNode *p,*q;p=root; //q要记录p的双亲位置
while(p!=NULL)
{
q=p;
if(k<p->data)p=p->lch;
else p=p->rch;
}
if(q->data<k)q->rch=s;
else q->lch=s;
delete p;} //不可以delete q,q是原来树中存在的结点
}
}
BstNode* BstTree::insertNode(BstNode *rt, BstNode *s)
{
if(rt==NULL)rt=s;
else if(s->data<rt->data)rt->lch=insertNode(rt->lch,s);
else rt->rch=insertNode(rt->rch,s);
return rt;
}
void main()
{
BstTree bsttree;
bsttree.NorecCreat();
bsttree.inorder();cout<<endl;
bsttree.deleteNode(bsttree.root,bsttree.root,NULL);
bsttree.inorder();
}
//sample input : 6
//10 3 18 6 20 2
//output: 2 3 6 10 18 20 中序遍历