二叉搜索树也称为二叉排序树。也就是说,插入的第一个数据作为根节点,后来的结点跟其根结点比,小的插在左边,大的插在右边。下面给举个例子:
由45,60 ,30 ,20 ,25 ,55 ,65 ,50, 40 ,35 。这几个树可以构成型如下面的一棵排序二叉树。
1、二叉搜索树的性质:
(1)每个结点都有一个作为搜索依据的关键码(key)也就是数据域,所有节点的关键码互不一样。
(2)左子树(如果存在)上的所有结点的关键码都小于根结点的关键码。
(3)右子树(如果存在)上的所有结点的关键码都大于根结点的关键码。
(4)左右子树也是二叉搜索树。
2、代码及解析:
下面我主要实现了这么一些功能:
int insert_val(T &x){return insert_val(root,x);} //--------------------------------------插入结点。
int remove(T key){return remove(root,key);}//----------------------------------------删除结点。
T max(){return max(root);}//---------------------------------------------------------------找最大值。
T min(){return min(root);}//----------------------------------------------------------------找最小值。
void sort(){sort(root);} //这里的sort就相当于中序遍历。因为排序树中序遍历就是从小到大的。
#include"AllHead.h"
template<class T>
class sortBinTree;
template<class T>
class sortBinTreeNode
{
friend class sortBinTree<T>;
private:
sortBinTreeNode<T> *left;
sortBinTreeNode<T> *right;
T data;
public:
sortBinTreeNode():left(NULL),right(NULL){}
sortBinTreeNode(T d):data(d),left(NULL),right(NULL){}
T getData(){return data;}
};
template<class T>
class sortBinTree
{
public:
sortBinTreeNode<T> *root;
public:
sortBinTree(sortBinTreeNode<T> *ptr = NULL):root(ptr){}
public:
//注意这个插入函数一定要有返回值,否则相当于没插进去
int insert_val(T &x){return insert_val(root,x);}
T max(){return max(root);}
T min(){return min(root);}
//这里的sort就相当于中序遍历。因为排序树中序遍历就是从小到大的。
void sort(){sort(root);}
int remove(T key){return remove(root,key);}
sortBinTreeNode<T>* find(T x){return find(root,x);}
protected:
sortBinTreeNode<T>* find(sortBinTreeNode<T> *t,T key)
{
if(t == NULL)
return NULL;
else if(t->data == key)
return t;
else if(t->data > key)
return find(t->left,key);
else
return find(t->right,key);
}
//删除排序树的结点的主要思想:
//如果要删的这个结点是叶子结点的话就直接删除,
//否则的话找到其左子树中的最大的那个结点,把它放在要删的那个位置,然后删掉那个左子树中最大的结点
//或者找到其右子树中的最小的那个结点,把它放在要删的那个位置,然后删掉那个右子树中最小的结点
int remove(sortBinTreeNode<T> *&t,T key)
{
if(t == NULL)
return FALSE;
if(key < t->data)
remove(t->left,key);
else if(key > t->data)
remove(t->right,key);
else
{
sortBinTreeNode<T> *p = NULL;
if(t->left != NULL && t->right != NULL)
{
p = t->left;
while(p->right != NULL)
p = p->right;
t->data = p->data;
remove(t->left,p->data);
}
else
{
p = t;
if(t->left == NULL)
t = t->right;
else
t = t->left;
delete p;
return TRUE;
}
}
}
void sort(sortBinTreeNode<T> *p)
{
if(p != NULL)
{
sort(p->left);
cout<<p->data<<"-->";
sort(p->right);
}
}
T min(sortBinTreeNode<T> *p)//这个传参千万不能传引用,因为这样会改变根节点的指向的。
{
if(p != NULL)
{
while(p->left != NULL)
p = p->left;
return p->data;
}
}
T max(sortBinTreeNode<T> *p)
{
if(p != NULL)
{
while(p->right != NULL)
p = p->right;
return p->data;
}
}
int insert_val(sortBinTreeNode<T> *&p,T &x)
{//按照小的在左边,大的在右边构造。
if(p == NULL)
{
p = new sortBinTreeNode<T>(x);
assert(p != NULL);
return OK;
}
else if(p->data > x)
{
insert_val(p->left,x);
}
else if(p->data < x)
{
insert_val(p->right,x);
}
else
return ERROR;
}
};
3、下面是我的测试主函数:
#include"sortBinTree.h"
int main()
{
sortBinTree<int> sbt;
sortBinTreeNode<int> *finval;
int i;
int val[] = {45,12,63,3,37,100,61};
int max;
int min;
int n = sizeof(val)/sizeof(int);
for(i = 0;i<n;i++)
{
sbt.insert_val(val[i]);
}
sbt.sort();
cout<<endl;
cout<<"最大值:"<<sbt.max()<<endl;
cout<<"最小值:"<<sbt.min()<<endl;
sbt.remove(63);
sbt.sort();
cout<<endl;
finval = sbt.find(63);
if(finval !=NULL)
cout<<(*finval).getData()<<endl;
else
cout<<"找不到...."<<endl;
}