概念:二叉排序树也叫二叉搜索树,1.若它的左子树非空,则左子树上所有结点的值均大于根结点的值。2.若它的右子树非空,则右子树上所有结点的值均大于根结点的值 3.它的左右子树也叫二叉排序树
二叉排序树的查找:
二叉排序树中value的结点。
1.从根结点开始,设p指向根结点。
2.将value与p结点的关键字进行比较,若俩者相等,则查找成功;若value值较小,则在p的左子树中继续查找;若value值较大,则在p的右子树中继续查找
3.重复执行上一步,直到查找成功或p为空。若p为空,则查找不成功。
一次查找经过从根结点到某结点的一条路径而不需要遍历整棵树,若查找成功则到达指定结点,否则经过某个叶子结点。因此二叉排序树能够提供快速查找。
二叉排序树的插入:
一颗二叉排序树插入结点之后必须任然是二叉排序树。每插入一个结点,首先需要找到该结点在二叉排序树中的位置,若具有相同关键字的结点已在二叉排序树中,则不插入;否则将新结点作为叶子结点,链接在其查找不成功时的一条路径之尾,该路径从根结点到某个原叶子结点。
二叉排序树的删除:
在二叉排序树种删除一个结点,首先查找该结点,若存在,则根据二叉排序树不同程度的调整,使删除结点的二叉树仍然是二叉排序树。设p是待删除的结点,parent指向p的父母结点。根据p结点的度不同,分暗中情况。
1.p是叶子结点。若p是parent的左孩子,删除p结点并设置parent的left链为空。
2.p是度为1的结点,删除p结点并用p的孩子填补作为parent的孩子,
若p是parent的左孩子且p有左孩子,设置parent的left链指向p的左孩子
若p是parent的左孩子且p有右孩子,设置parent的left链指向p的右孩子
若p是parent的右孩子且p有左孩子,设置parent的right链指向p的左孩子
若p是parent的右孩子且p有右孩子,设置parent的left链指向p的右孩子
3.p为度为2的结点,不直接删除p结点,而是首先用p在中根次序下的后继结点innext值代替p结点值,再删除innext结点,这样讲删除度为2的结点的问题转化为删除度为1的结点或叶子结点,使得对二叉排序树的调整减少到最小程度。
#include "BinaryTree.h" //二叉链表的二叉树类
template <class T>
class BinarySortTree : public BinaryTree<T> //二叉排序树类,继承二叉树类
{
public:
BinarySortTree ():BinaryTree<T> () {} //构造空二叉排序树,调用基类构造函数
~BinarySortTree () {}
DoubleNode <T>*Search (T value);//查找首次出现值为value的结点
DoubleNode<T> *Insert (T value); //插入
bool Remove (T value); //删除
DoubleNode<T>*SearchNode (T value); // 查找值为value的结点
bool InsertNode(T value); //插入结点,非递归算法
private:
DoubleNode<T>* Insert (DoubleNode <T>*p, T value); // 将value插入到以p为根的子树中
bool Remove (T value, DoubleNode <T> *p,DoubleNode<T> *parent); //在以p为根的子树中删除value
DoubleNode<T> *SearchNode (DoubleNode<T> *p, T value);
};
template <class T>
DoubleNode<T> *BinarySortTree<T>::Search(T value) //查找首次出现值value的结点
{
DoubleNode<T> *p=this->root;
while(p! = NULL && p->data! = value) //当没有相等者
{
cout<<p->data <<"?"; //显示查找经过的结点值,可省略
if(value<p->data) //若value较小
p = p->prior;//进入左子树
else
p = p->next; //进入右子树
}
return p;
}
template<class T>
DoubleNode<T>* BinarySortTree<T>::Insert (T value) //插入结点,不插入关键字重复的结点
{
if(this->root == NULL)
{
this->root = new DoubleNode<T> (value);
return this->root;
}
return Insert (this ->root, value); //插入value到以root为根的二叉排序树中
}
template <class T>
DoubleNode<T>* BinarySortTree<T>::Insert(DoubleNode<T> *p, T value) //将value插入到以p为根的子树中
{
DoubleNode<T>* q=NULL;
if(p->data == value)
return NULL;
if(value<p->data)
if(p->prior == NULL)
{
q = new DoubleNode<T> (value);
p->prior = q;
return q;
}
else
return Insert (p->prior, value);
else
if(p->next == NULL)
{
q = new DoubleNode<T> (value);
p->next = q; //建立叶子结点作为p的右孩子
return q;
}
else
return Insert(p->next, value);
}
template <class T>
bool BinarySortTree<T>::Remove(T value)
{
return this->root!=NULL&&Remove (value, this->root,NULL);
}
template <class T>
bool BinarySortTree<T>::Remove(T value, DoubleNode<T> *p, DoubleNode<T> *parent)
//在以p为根的子树中删除value,parent是p的父母结点,递归算法
{
if(value<p->data)
return Remove(value, p->prior,p);
else
if(p->prior!=NULL&&p->next!=NULL) //p是度为2的结点
{
DoubleNode<T>* innext =p->next;
while(innext -> prior!= NULL)
innext = innext->prior;
p->data = innext->data;
return Remove (p->data,p->next,p);
}
else
{
if(parent ==NULL)
{
if(p->prior!=NULL)
this->root = p->prior;
else
this->root = p->next;
return true;
}
if(p==parent ->prior)
if(p->prior!=NULL)
parent->prior = p->prior;
else
parent->prior = p->next;
else
if(p->prior! = NULL)
parent ->next = p->prior;
else
parent ->next = p->next;
return true;
}
return flase;
}
#define _CRT_SECURE_NO_WARNINGS
#include<iostream.h>
#include"BinarySortTree.h"
int main()
{
const int N = 16;
int keys[] ={54,18,66,87,36,12,54,81,15,76,57,6,40,99,85,99};
cout<<"插入:";
BinarySortTree<int> bstree;
for(int i=0;i<N;i++)
if(bstree.Insert(keys[i])!=NULL)
cout<<keys[i]<<" ";
cout<<endl;
bstree.midRoot();
cout<<"查找"<<keys[N-1]<<","<<(bstree.SearchNode(keys[N-1])!=NULL?"":"不")<<"成功\n";
cout<<"查找50,"<<(bstree.SearchNode(50)!=NULL?" ":"不")<<"成功\n";
return 0;
}