二叉排序树的定义
- 若左子树不空,二叉树的根结点的值小于其左子树的所有结点的值
- 若右子树不空,二叉树的根结点的值大于或等于其右子树的所有结点的值
- 其所有的左右子树均为二叉排序树
二叉排序树的查找
非递归查找
btNode* searchNR(btNode* T, elementType x){
while (T){//如果根结点指针不为空
if (x < T->data)
T = T->lChild;//继续访问左子树
else if (x > T->data)
T = T->rChild;//继续访问右子树
else
return T;//查找成功
}
return NULL;//查找失败
}
递归查找
btNode* search(btNode* T, elementType x){
while (T){//如果根结点不为空
if (x < T->data)
return search(T->lChild);//继续访问左子树
else if (X > T->rChild)
return search(T->rChild);//继续访问右子树
else
return T;//查找成功
}
return NULL;//查找失败
}
二叉排序树的插入
插入结点的非递归算法
void insertNR(btNode* T, btNode *p){
while (T){//如果当前结点指针不为空
if (p->data < T->data)
T = T->lChild;
else
T = T->rChild;
}
//插入的位置一定在叶子结点上
T = p;
}
插入结点的递归算法
void InsertNode(btNode *&T, btNode *p) //插入指针为p的结点
{
if(T==NULL)
T=p; //空树,p插入为根结点
else if(p->data<T->data)
InsertNode(T->lChild,p); //p的值小于根结点值,p插入左子树
else
InsertNode(T->rChild,p); //p的值大于等于根结点值,p插入右子树
}
二叉排序树的构建
void CreateBst(btNode *&T){
elementType x;
btNode* p;
T = NULL; //初始化根结点指针
cout << "输入要构建的二叉排序树的结点元素(输入-9999构建结束):";
cin >> x;
while (x != -9999){
p=new btNode;
p->data=x;
p->lChild=NULL;
p->rChild=NULL;
insert(T, p);
cin >> x;
}
}
二叉树删除结点
顶替法
int DelNode(btNode *&T, elementType x){
btNode *p, *pf, *s;
if (T == NULL)
return 0;//空树
//查找要删除的元素
p = T;
pf = T;
while (p){
if (p->data == x)
break;
else if (p->data < x){
pf = p;
p = p->lChild;
}
else{
pf = p;
p = p->rChild;
}
}
//首先判断元素是否存在
if (p==NULL){
cout << "元素查找失败!" << endl;
return 1;
}
//判断要查找的是否是根结点
if (p == pf){
cout << "要删除的元素是根结点" << endl;
}
//如果p没有左孩子结点,包括p指向叶子结点
if (p->lChild == NULL){
//先考虑p指向根结点的情况
if (pf == p)
T = p->rChild;
if (pf->lChild == p)
pf->lChild = p->rChild;
else
pf->rChild = p->rChild;
}
//如果p没有右孩子结点
else if (p->rChild == NULL){
//先考虑p指向根结点的情况
if (pf == p)
T = p->lChild;
if (pf->lChild == p)
pf->lChild = p->lChild;
else
pf->rChild = p->lChild;
}
//直接前驱顶替法
else {
//找到p的前驱结点
s = p->lChild;
pf = p;//pf现在是s的父结点指针
while (s->rChild){
pf = s;
s = s->rChild;
}
p->data = s->data;
if (pf == p)
sf->lChild = s->lChild;
else
sf->rChild = s->lChild;
delete s;
}
/* { //顶替法2
//p的左、右子树皆不空,p的中序直接后继替代,即p右子树最小值结点替代
pf=p;
s=p->rChild;
while(s->lChild)
{
pf=s;
s=s->lChild;
}
p->data=s->data;
if(pf==p) //s为p(pf)右子树的根结点,且没有左子树,s即为p的直接后继。将s的右子树接续为pf(p)的右子树
pf->rChild=s->rChild;
else //s接续为pf的左子树
pf->lChild=s->rChild;
delete s;
}
*/
return 2; //删除成功
}
重接法
//重接法删除结点算法
int DelNode1(btNode *&T, elementType x)
{
btNode *p,*s,*pf; //p指删除结点,pf指p的父结点
if(T==NULL)
return 0;//空树删除失败
//搜索待删除结点p,及其父结点指针pf
p=T;
pf=T;
while(p)
{
if(p->data==x) //找到目标结点,退出循环
break;
else if(p->data>x) //搜索左子树
{
pf=p;
p=p->lChild;
}
else //搜索右子树
{
pf=p;
p=p->rChild;
}
}
if(p==NULL) //目标结点不存在,删除失败
return 0;
//下面开始删除结点p,其父结点为pf
if(p->lChild==NULL) //p没有左子树,或叶子结点,用右子树的根结点替代p
{
if(pf==p) //删除的是根结点
T=p->rChild;
else
{
if(pf->lChild==p)
pf->lChild=p->rChild;
else
pf->rChild=p->rChild;
}
delete p;
}
else if(p->rChild==NULL) //p没有右子树
{
if(pf==p) //删除的是根结点
T=p->lChild;
else
{
if(pf->lChild==p)
pf->lChild=p->lChild;
else
pf->rChild=p->lChild;
}
delete p;
}
else
/*
{ //重接法1
//p的左、右子树皆不空,p的左子树重接为pf的子树(左子树或右子树),p的右子树重接为p的直接前趋结点s的右子树(s原没有右子树)
s=p->lChild;
while(s->rChild)
{
s=s->rChild;
}
if(pf==p) //删除根结点,p的左子树根结点成为新的根结点
T=p->lChild;
else if(pf->lChild==p) //p的左子树重接为pf的左子树
pf->lChild=p->lChild;
else //p的左子树重接为pf的右子树
pf->rChild=p->lChild;
//p的右子树重接为p的直接前趋s的右子树(s原没有右子树)
s->rChild=p->rChild;
delete p;
}
*/
{ //重接法2
//p的左、右子树皆不空,p的右子树重接为pf的子树(左子树或右子树),p的左子树重接为p的直接后继结点s的左子树(s原没有左子树)
//搜索p的直接后继
s=p->rChild;
while(s->lChild)
{
s=s->lChild;
}
if(pf==p) //删除根结点,p的右子树根结点成为新的根结点
T=p->rChild;
else if(pf->lChild==p) //p的右子树重接为pf的左子树
pf->lChild=p->rChild;
else //p的右子树重接为pf的右子树
pf->rChild=p->rChild;
//p的左子树重接为p的直接后继s的左子树(s原没有左子树)
s->lChild=p->lChild;
delete p;
}
/* {
//p的左、右子树皆不空,p的中序直接后继替代,即p右子树最小值结点替代
pf=p;
s=p->rChild;
while(s->lChild)
{
pf=s;
s=s->lChild;
}
p->data=s->data;
if(pf==p) //s为p(pf)右子树的根结点,且没有左子树,s即为p的直接后继。将s的右子树接续为pf(p)的右子树
pf->rChild=s->rChild;
else //s接续为pf的左子树
pf->lChild=s->rChild;
delete s;
}
*/
return 1;
}