Bst(Binary Search Tree)
有以下性质:
-
每一个元素有一个键值,而且不予许重复
-
左子树的键值都小于根节点的键值
-
右子树的键值都大于根节点的键值
-
左右子树都是二叉查找树
代码:
#ifndef __BST_H__
#define __BST_H__
#include<iostream>
using namespace std;
template <class T> class Bst; //声明
enum Boolean {False,True};
template<class T>
class Element //数据
{
public:
T Key; //定义键值
};
template<class T>
class BstNode //定义结点
{
friend class Bst<T>;
public:
Element<T> data; //结点数据
BstNode *LeftChild; //左孩子
BstNode *RightChild;//右孩子
void display(int i); //显示
};
template<class T>
class Bst //定义二叉查找树
{
public:
Bst(BstNode<T>*init=0) //定义构造函数
{
root=init;
}
Boolean Insert(Element<T>&x); //插入元素
BstNode<T>* Search(const Element<T>&x); //递归查找
BstNode<T>* Search(BstNode<T>*p,const Element<T>&x);
BstNode<T>* ItearSearch(const Element<T>&x); //采用迭代方式查找
void display()
{
cout<<endl;
if(root)
root->display(1); //根从1开始显示
}
void Preorder(BstNode<T> *CurrentNode); //前序遍历
void Inorder(BstNode<T> *CurrentNode); //中序遍历
void Postorder(BstNode<T> *CurrentNode);//后序遍历
void Vivit(BstNode<T> *CurrentNode); //当前节点
//private:
BstNode<T>*root; //根结点
};
template<class T>
void BstNode<T>::display(int i) //显示数据
{
cout<<"Position: "<<i<<" Data:"<<data.Key<<endl; //显示位置和数据
if(LeftChild) LeftChild->display(2*i); //显示左孩子
if(RightChild) RightChild->display(2*i+1); //显示右孩子
}
template<class T>
Boolean Bst<T>::Insert(Element<T>&x) //插入数据
{
//插入数据之前需要查找数据
BstNode<T> *p=root; //初始指向根节点
BstNode<T> *q=0; //用来保存上一个父节点
while(p)
{
q=p; //保存上一个父节点
if(x.Key==p->data.Key) return False; //如果节点存在 则返回错误
if(x.Key>p->data.Key) p=p->RightChild; //如果节点父节点大,则放到右节点
else p=p->LeftChild; //否则,放到左节点
}
//找到的位置就是q
p=new BstNode<T>;
p->LeftChild=p->RightChild=0; //刚开始令左孩子和右孩子都等于0
p->data=x;
if(!root) root=p; //如果根不存在 p就是根
else if(x.Key>q->data.Key) q->RightChild=p; //键值比父节点大,则放到右孩子
else q->LeftChild=p; //否则,放到左孩子
return True; //返回正确
}
template<class T>
BstNode<T>* Bst<T>::Search(const Element<T>&x) //查找
{
return Search(root,x); //从根开始查找
}
template<class T>
BstNode<T>* Bst<T>::Search(BstNode<T>*p,const Element<T>&x)
{
if(!p) return 0; //如果b不存在 返回0
if(x.Key==p->data.Key) return p; //找到了 返回p
if(x.Key>p->data.Key) Search(p->RightChild,x); //比父节点大 从右开始找
else Search(p->LeftChild,x); //否则 从左开始找
}
template<class T>
BstNode<T>* Bst<T>::ItearSearch(const Element<T>&x)//采用迭代方式查找
{
BstNode<T>*p;
for(p=root;p;) //p等于root p有效就一直查找
{
if(x.Key==p->data.Key) return p;
if(x.Key>p->data.Key) p=p->RightChild; //如果大于则p指向下一个右孩子
else p=p->LeftChild; //否则 指向左孩子
}
//循环结束都没找到
return 0; //
}
static int cnt=0; //节点数
/*遍历*/
template<class T>
void Bst<T>::Vivit(BstNode<T> *CurrentNode)
{
cout<<CurrentNode->data.Key<<' '; //显示当前数据键值
}
template<class T>
void Bst<T>::Preorder(BstNode<T> *CurrentNode)//前序遍历
{
if(CurrentNode)
{
Vivit(CurrentNode);
Preorder(CurrentNode->LeftChild); //左子树
Preorder(CurrentNode->RightChild); //右子树
}
}
template<class T>
void Bst<T>::Inorder(BstNode<T> *CurrentNode)//中序遍历
{
if(CurrentNode)
{
Preorder(CurrentNode->LeftChild); //左子树
Vivit(CurrentNode);
Preorder(CurrentNode->RightChild); //右子树
}
}
template<class T>
void Bst<T>::Postorder(BstNode<T> *CurrentNode)//后序遍历
{
if(CurrentNode)
{
Preorder(CurrentNode->LeftChild); //左子树
Preorder(CurrentNode->RightChild); //右子树
Vivit(CurrentNode);
}
}
#endif // __BST_H__
main
#include <iostream>
#include "BST.h"
using namespace std;
int main()
{
Bst<int> p;
Element<int>a,b,c,d,e,f,g,h,i,l,k;
a.Key=5;
b.Key=3;
c.Key=11;
d.Key=3;
e.Key=15;
f.Key=2;
g.Key=8;
h.Key=22;
i.Key=20;
l.Key=9;
cout<<p.Insert(a)<<endl;
cout<<p.Insert(b)<<endl;
cout<<p.Insert(c)<<endl;
cout<<p.Insert(d)<<endl;
cout<<p.Insert(e)<<endl;
cout<<p.Insert(f)<<endl;
cout<<p.Insert(g)<<endl;
cout<<p.Insert(h)<<endl;
cout<<p.Insert(i)<<endl;
cout<<p.Insert(l)<<endl;
p.display();
BstNode<int> *m=p.ItearSearch(i);
cout<<m->data.Key<<endl;
//cout << "Hello world!" << endl;
cout<<"前序遍历"<<endl;
p.Preorder(p.root);
return 0;
}