(1)二叉排序树定义:
该二叉树或者是一棵空树或者是一棵具有下列性质的树:
1. 若他的左子树非空,则左子树上所有节点的值均小于根节点的值
2. 若他的右子树非空,则右子树上所有节点的值均大于(等于)根节点的值
3. 他的左子树与与右子树也分别是二叉排序树
二叉排序树的插入
思路:
1. 首先判断二叉树是否为空,若为空则可以直接把当做根节点
2. 若非空,则key与根节点进行比较
a. 如果Key等于节点的值 则停止插入
b. 如果Key大于节点的值 则插入根节点右边
c. 如果Key小于节点的值 则插入根节点左边
代码实现:
void insertBST(PBSTNode *root,int key)
{
if (*root == NULL)
{
PBSTNode pNew = new BSTNode;
pNew->key = key;
pNew->lchild = pNew->rchild = NULL;
*root = pNew;
return;
}
else
{
if (key > (*root)->key)
{
insertBST(&(*root)->rchild, key);
}
else
{
insertBST(&(*root)->lchild, key);
}
}
}
二叉排序树的创建
void CreatBST(PBSTNode * root)
{
int key;
cin >> key;
while (-1 != key)
{
insertBST(root, key);
cin >> key;
}
}
二叉排序树的查找
思路:
1. 首先判断二叉树是否为空,若为空则不可查找
2. 若非空,则key与根节点进行比较
a. 如果Key等于节点的值 则查找成功
b. 如果Key大于节点的值 则根节点右边查找
c. 如果Key小于节点的值 则根节点左边查找
PBSTNode BSTSearch(PBSTNode root,int key)
{
if (NULL == root)
{
cout << "该查找树为空!" << endl;
return NULL;
}
if (root->key == key)
{
return root;
}
else if (root ->key < key)
{
return BSTSearch(root->rchild, key);
}
else
{
return BSTSearch(root->lchild, key);
}
}
二叉排序树的删除
在二叉排序树删去一个结点,分三种情况讨论:
1. 若*p结点为叶子结点,即PL(左子树)和PR(右子树)均为空树。由于删去叶子结点不破坏整棵树的结构,则可以直接删除此子结点。
2. 若*p结点只有左子树PL或右子树PR,此时只要令PL或PR直接成为其双亲结点*f的左子树(当*p是左子树)或右子树(当*p是右子树)即可,作此修改也不破坏二叉排序树的特性。
3. 若*p结点的左子树和右子树均不空。在删去*p之后,为保持其它元素之间的相对位置不变,可按中序遍历保持有序进行调整,可以有两种做法:
A:其一是令*p的左子树为*f的左/右(依*p是*f的左子树还是右子树而定)子树,*s为*p左子树的最右下的结点,而*p的右子树为*s的右子树
B:其二是令*p的直接前驱(或直接后继)替代*p,然后再从二叉排序树中删去它的直接前驱(或直接后继)-即让*f的左子树(如果有的话)成为*p左子树的最左下结点(如果有的话),再让*f成为*p的左右结点的父结点。
代码如下:
PBSTNode delBST(PBSTNode root, int key)
{
PBSTNode p,fa,s,q;
fa = NULL;
p = root;
while (p)
{
if (p->key == key)
{
break;
}
else if (p->key > key)
{
fa = p;
p = p->lchild;
}
else
{
fa= p;
p = p->rchild;
}
}
if (p == NULL)
{
cout << "没有查到该值!" << endl;
return root;
}
if (p->lchild == NULL)
{
if (fa == NULL)
{
root = p->rchild;
}
else if (fa->lchild == p)
{
fa->lchild = p->rchild;
}
else
{
fa->rchild = p->rchild;
}
delete p;
}
else
{
s = p->lchild;
q = p;
while (s)
{
p = s;
s = p->rchild;
}
if (p == q)
{
q->lchild = s->lchild;
}
else
{
q->rchild = s->lchild;
}
p->key = s->key;
delete s;
}
return root;
}