二叉排序树是为了实现数据的有序排列,并可方便的对树中的数据进行插入和删除操作,提高查找效率。BST

这里删除和添加都需要设计到查找的操作,所以要使其效率高的话,就要提升查找操作的效率。AVL:平衡二叉树

二叉排序树_子树

性质:

若它的左子树不为空,则左子树上的所有值均小于根结点的值
若它的右子树不为空,则右子树上的所有值均大于根结点的值
它的左右子树也分别为二叉排序树
左小于中小于右

操作:
查找

二叉排序树是一个有序的二叉树,其左子树永远比根节点的值小,右子树用于比根节点的值大。因此我们可以使用递归技术,如果keydata,则在p的左子树里面继续寻找;若key>p->data则在p的右子树里面继续寻找;直到key=p->data;否则表示未搜索到,退出函数。实现过程如下图:

二叉排序树_子树_02

插入

插入的关键是,在插入元素后还要继续保持二叉树的有序性。实现过程如下图:

二叉排序树_子树_03

删除

二叉排序树的难点是删除操作。

删除结点分三种情况:

结点没有左右孩子;
结点只有左子树或右子树;
结点左右子树均有;
结点没有左右孩子:

解决办法:删除该结点,将该结点的双亲指针域置为NULL

结点只有左子树或右子树:

解决办法:删除该结点,将该结点的双亲指针域指向该结点的左子树或右子树。

结点左右子树均有:

解决办法:保留该结点,将该结点的数据域改为该结点直接前驱(或直接后继)结点的值,删除该结点的直接前驱结点。

实现过程如下图:

二叉排序树_二叉树_04

代码:
C++

#include 
using namespace std;

//二叉树结点
template
struct BTNode
{
T data; //存储数据
BTNode *lchild, *rchild; //左右孩子指针
BTNode(T D, BTNode *l = NULL, BTNode *r = NULL) : data(D), lchild(l), rchild(r) {}
};

//二叉树
template
class BST
{
//属性值
private:
//根节点指针
BTNode *root;
//查找结点
bool SearchBSTP(BTNode *rt, T key, BTNode *&p = NULL, BTNode *f = NULL)
{
if (!rt) //查找失败
{
p = f;
return false;
}
else if (key == rt->data) //查找成功
{
p = rt;
return true;
}
else if (key > rt->data)
{
return SearchBSTP(rt->rchild, key, p, rt); //在右子树继续查找
}
else
{
return SearchBSTP(rt->lchild, key, p, rt); //在左子树继续查找
}
}
//插入结点
bool Insert(BTNode *&rt, T key)
{
BTNode *p = NULL;
if (!this->SearchBSTP(rt, key, p))
{
BTNode *s = new BTNode(key, NULL, NULL);
if (!p)
{
rt = s;
}
else if (key < p->data)
{
p->lchild = s;
}
else
{
p->rchild = s;
}
return true;
}
else
{
return false;
}
}
//删除结点
bool Delete(BTNode *&p)
{
BTNode *q;
if(!p->lchild)
{
q=p;
p=p->rchild;
delete q;
}
else if (!p->rchild)
{
q=p;
p=p->lchild;
delete q;
}
else
{
BTNode *s=p;
q=p->lchild;
while(q->rchild)
{
s=q;
q=q->rchild;
}
p->data=q->data;
if(s!=p)
{
s->rchild=q->lchild;
}
else
{
s->lchild=q->lchild;
}
delete q;
}
return true;
}

bool DeleteBSTP(BTNode *&rt,T key)
{
if(!rt)
{
//未找到
return false;
}
else
{
if(rt->data==key)
{
//找到key
return Delete(rt);
}
else if (rt->data>key)
{
return DeleteBSTP(rt->lchild,key);
}
else
{
return DeleteBSTP(rt->rchild,key);
}
}
}
//中序遍历
void InOrder(BTNode *rt)
{
if(rt)
{
InOrder(rt->lchild);
cout<data<<" ";
InOrder(rt->rchild);
}
}
//删除二叉树
void Destory(BTNode *&rt)
{
if(rt)
{
Destory(rt->lchild);
Destory(rt->rchild);
delete rt;
}
}
//行为属性
public:
//构造函数
BST(BTNode *r = NULL) : root(r) {}
//拷贝构造函数
BST(const BST &bt) : root(NULL)
{
}
//删除二叉树
void Destory()
{
this->Destory(this->root);
this->root=NULL;
}
//析构函数
~BST()
{
this->Destory();
}
//获得根指针
BTNode *Getroot()
{
return this->root;
}
//搜索值
//并将
bool SearchBST(T key, BTNode *p = NULL)
{
return this->SearchBSTP(this->root, key, p, NULL);
}
//插入结点,顺序插入
/*1、先判断此值是否存在,若存在,则返回true
2、若不存在,创造结点s,并顺序插入二叉树中
3、若不存在,则存在指针p指向查找路径的最后一个结点
4、判断插入值和指针p指向的值的大小,若key>p->data,则p->rchild=s;
否则p->lchild=s;
*/
bool InsertBST(T key)
{
return this->Insert(this->root, key);
}
//shanchujiedian
bool DeleteBST(T key)
{
return this->DeleteBSTP(this->root, key);
}

void InOrder()
{
this->InOrder(this->root);
}
};

int main()
{
BST temp;
int a[] = {62,58,88,47,73,99,35,51,93,29,37,49,56,36,48,50};
for (int i = 0; i < 16; i++)
{
temp.InsertBST(a[i]);
}
temp.InOrder();
cout< //BTNode *p;
cout << "查找结果:" << temp.SearchBST(51) << endl;
temp.DeleteBST(62);
cout << "查找结果:" << temp.SearchBST(50) << endl;
temp.InOrder();
cout< temp.Destory();
temp.InOrder();
cout<
system("pause");
return 0;
}