//genBST.h
#ifndef GENBST_H_INCLUDED
#define GENBST_H_INCLUDED
#include <queue>
#include <stack>
using namespace std;
template <class T>
class Stack:public stack<T>{};
template <class T>
class Queue:public queue<T>{
public:
T dequeue(){
T tmp = this->front();
queue<T>::pop();
return tmp;
}
void enqueue(const T& el){
this->push(el);
}
};
template <class T>
class BSTNode{
public:
BSTNode(){
left = right = 0;
}
BSTNode(const T&e,BSTNode<T> * l=0,BSTNode<T>*r=0){
el = e;left =l;right =r;
}
T el;
BSTNode<T> *left,*right;
};
template <class T>
class BST{
public:
BST(){
root = 0;
}
~BST(){
clear();
}
void clear(){
clear(root);root = 0;
}
bool isEmpty()const{
return root==0;
}
bool isBalance(){
return isBalance(root);
}
bool isComplate(){
return isComplate(root);
}
bool isBinarySort(){
return isBST(root);
}
void preorder(){
preorder(root);
}
void inorder(){
inorder(root);
}
void postorder(){
postorder(root);
}
T *search(const T& el)const{
return search(root,el);
}
int pointNum(){
return pointNum(root);
}
int leafNum(){
return leafNum(root);
}
int rightNum(){
return rightNum(root);
}
int deep(){
return deep(root);
}
void makefree(){
makefree(root);
}
void breadthFirst();
void iterativePreorder();
void iterativeInorder();
void iterativePostorder();
void iterInorder();
void MorrisInorder();
void insert(const T&);
void deleteByMerging(BSTNode<T>*&);
void findAndDeleteByMerging(const T&);
void deleteByCopying(BSTNode<T>*&);
void findAndDeleteByCopying(const T&);
void balance(T*,int,int);
protected:
BSTNode<T> * root;
void clear(BSTNode<T>*);
T*search(BSTNode<T>*,const T&)const;
void preorder(BSTNode<T>*);
void inorder(BSTNode<T>*);
void postorder(BSTNode<T>*);
void makefree(BSTNode<T>*);
int pointNum(BSTNode<T>*);
int leafNum(BSTNode<T>*);
int rightNum(BSTNode<T>*);
int deep(BSTNode<T>*);
virtual void visit(BSTNode<T>*p){
cout<<p->el<<" ";
}
bool isBalance(BSTNode<T>*);//递归判断是否是平衡二叉树,多次遍历
bool isComplate(BSTNode<T>*);//用队列是否是完全二叉树,如果tag=0,说明出现叶子节点,那么它后面的节点就都是叶子节点了。
bool isBinarySort(BSTNode<T>*);//用队列判断是否是二叉排序树
bool isBST(BSTNode<T>*);//中序遍历判断是否是二叉排序树
};
template<class T>
bool BST<T>::isBST(BSTNode<T>*p){
stack<BSTNode<T>*> s;
BSTNode<T>* pre =0;
while(p||!s.empty()){
if(p){
s.push(p);
p=p->left;
}
else{
p = s.top();
s.pop();
if(pre&&(pre->el >= p->el))
return false;
pre = p;
p=p->right;
}
}
return true;
}
template<class T>
bool BST<T>::isBinarySort(BSTNode<T>*p){
if(p==0)
return true;
queue <BSTNode<T>*> q;
q.push(p);
while(!q.empty()){
p=q.front();
q.pop();
if(p->left)
if(p->left->el < p->el)
q.push(p->left);
else
return false;
if(p->right)
if(p->right->el>p->el)
q.push(p->right);
else
return false;
}
return true;
}
template<class T>
bool BST<T>::isComplate(BSTNode<T>*p){
queue<BSTNode<T>*> q;
if(p==0)
return true;
int tag =0;
q.push(p);
while(!q.empty()){
p=q.front();
q.pop();
if(p->left&&!tag)
q.push(p->left);
else if(p->left)
return false;
else
tag =1;
if(p->right&&!tag)
q.push(p->right);
else if(p->right)
return false;
else
tag =1;
}
return true;
}
template<class T>
bool BST<T>::isBalance(BSTNode<T>*p){
if(p==0)
return true;
int left = deep(p->left);
int right = deep(p->right);
int diff = right - left;
if(diff>1 || diff <-1)
return false;
return (isBalance(p->right)&&isBalance(p->left));
}
template<class T>
void BST<T>::makefree(BSTNode<T>*p){
if(p!=NULL){
makefree(p->left);
makefree(p->right);
deleteByCopying(p);
}
}
template<class T>
int BST<T>::pointNum(BSTNode<T>*p){
if(p==0)
return 0;
int left = pointNum(p->left);
int right = pointNum(p->right);
int num = 1+left+right;
return num;
}
template<class T>
int BST<T>::leafNum(BSTNode<T>*p){
if(p==0)
return 0;
else if(p->left==0&&p->right==0)
return 1;
else
return leafNum(p->left)+leafNum(p->right);
}
template<class T>
int BST<T>::rightNum(BSTNode<T>*p){
if(p==0)
return 0;
else if(p->right)
return 1+ rightNum(p->left) + rightNum(p->right);
}
template<class T>
int BST<T>::deep(BSTNode<T>*p){
if(p==0)
return 0;
else{
if(deep(p->left) > deep(p->right))
return 1+deep(p->left);
else
return 1+deep(p->right);
}
}
template<class T>
void BST<T>::clear(BSTNode<T>*p){
while(p!=0){
if(p->left);
clear(p->left);
if(p->right);
clear(p->right);
delete(p);
}
}
//二叉查找树的查找
template<class T>
T* BST<T>::search(BSTNode<T>* p,const T& el) const{
while(p!=0){
if(el == p->el)
return &p->el;
else if(el < p->el)
p=p->left;
else
p=p->right;
}
return 0;
}
//广度优先遍历
template<class T>
void BST<T>::breadthFirst(){
Queue<BSTNode<T>*> queue;
BSTNode<T> * p =root;
if(p!=0){
queue.enqueue(p);
while(!queue.empty()){
p = queue.dequeue();
visit(p);
if(p->left!=0)
queue.enqueue(p->left);
if(p->right!=0)
queue.enqueue(p->right);
}
}
}
//递归的深度优先遍历
//先序、中序、后序遍历:
template<class T>
void BST<T>::preorder(BSTNode<T>*p){
if(p!=0){
visit(p);
preorder(p->left);
preorder(p->right);
}
}
template<class T>
void BST<T>::inorder(BSTNode<T>*p){
if(p!=0){
inorder(p->left);
visit(p);
inorder(p->right);
}
}
template<class T>
void BST<T>::postorder(BSTNode<T>*p){
if(p!=0){
postorder(p->left);
postorder(p->right);
visit(p);
}
}
//非递归的深度优先遍历
//先序、中序、后序遍历
template <class T>
void BST<T>::iterativePreorder(){
Stack<BSTNode<T>*> travStack;
BSTNode<T>*p = root;
if(p!=0){
travStack.push(p);
while(!travStack.empty()){
p=travStack.top();
travStack.pop();
visit(p);
if(p->right!=0)
travStack.push(p->right);
if(p->left!=0)
travStack.push(p->left);
}
}
}
template<class T> //难点
void BST<T>::iterativePostorder(){
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root, *q=root;
while(p!=0){
for(;p->left!=0;p=p->left)
travStack.push(p);
while(p->right ==0 || p->right ==q){
visit(p);
q = p;
if(travStack.empty())
return;
p = travStack.top();
travStack.pop();
}
travStack.push(p);
p=p->right;
}
}
/*对于任一结点P,将其入栈,然后沿其左子树一直往下搜索,直到搜索到没有左孩子的结点,此时该结点出现在栈顶,
但是此时不能将其出栈并访问,因此其右孩子还为被访问。所以接下来按照相同的规则对其右子树进行相同的处理,
当访问完其右孩子时,该结点又出现在栈顶,此时可以将其出栈并访问。
这样就保证了正确的访问顺序。可以看出,在这个过程中,每个结点都两次出现在栈顶,只有在第二次出现在栈顶时,才能访问它。
因此需要多设置一个变量标识该结点是否是第一次出现在栈顶。
*/
template<class T>
void BST<T>::iterativeInorder(){//此方法不好理解,下面的方法好理解
Stack<BSTNode<T>*> travStack;
BSTNode<T> *p = root;
while(p!=0){
while(p!=0){
if(p->right)
travStack.push(p->right);
travStack.push(p);
p=p->left;
}
p=travStack.top();
travStack.pop();
while(!travStack.empty()&&p->right==0){
visit(p);
p=travStack.top();
travStack.pop();
}
visit(p);
if(!travStack.empty()){
p=travStack.top();
travStack.pop();
}
else
p=0;
}
}
template<class T>
void BST<T>::iterInorder(){//此方法好理解
Stack<BSTNode<T>*> s;
BSTNode<T> * p = root;
while(p!=0 ||!s.empty()){
while(p!=0)
{
s.push(p);
p=p->left;
}
if(!s.empty()){
p=s.top();
visit(p);
s.pop();
p=p->right;
}
}
}
//插入
template<class T>
void BST<T>::insert(const T&el){
BSTNode<T> * p = root, *prev =0;
while(p!=0){
prev = p;
if(el<p->el)
p = p->left;
else p = p->right;
}
if(root ==0)
root = new BSTNode<T>(el);
else if(el<prev->el)
prev ->left = new BSTNode<T>(el);
else prev->right = new BSTNode<T>(el);
}
//删除,合并删除(考虑到要被删除的节点有左右两个子节点)
template <class T>
void BST<T>::deleteByMerging(BSTNode<T>*& node){
BSTNode<T> * tmp = node;
if(node !=0){
if(!node->right)
node = node->left;
else if(node->left==0)
node = node->right;
else{
tmp = node->left;
while(tmp->right!=0)
tmp = tmp->right;
tmp->right = node->right;
tmp = node;
node = node->left;
}
delete tmp;
}
}
//合并删除操作:
template<class T>
void BST<T>::findAndDeleteByMerging(const T&el){
BSTNode<T> *node =root, *prev =0;
while(node !=0){
if(node->el ==el)
break;
prev = node;
if(node->el <el)
node = node ->right;
else node = node->left;
}
if(node !=0 && node->el==el)
if(node == root)
deleteByMerging(root);
else if(prev->left == node)
deleteByMerging(prev->left);
else deleteByMerging(prev->right);
else if(node ==0)
cout <<"el "<<el<<" is not int the tree\n";
else cout<<"the tree is empty\n";
}
//复制删除
template<class T>
void BST<T>::deleteByCopying(BSTNode<T>*& node){
BSTNode<T> * previous,*tmp=node;
if(node->right ==0)
node = node->left;
else if(node->left ==0)
node = node->right;
else{
tmp = node->left;
previous = node;
while(tmp->right !=0){
previous = tmp;
tmp = tmp->right;
}
node->el = tmp->el;
if(previous == node)
previous->left = tmp->left;
else previous->right = tmp->left;
}
delete tmp;
}
//找到并进行复制删除
template<class T>
void BST<T>::findAndDeleteByCopying(const T&el){
BSTNode<T> *node =root, *prev =0;
while(node !=0){
if(node->el ==el)
break;
prev = node;
if(node->el <el)
node = node ->right;
else node = node->left;
}
if(node !=0 && node->el==el)
if(node == root)
deleteByCopying(root);
else if(prev->left == node)
deleteByCopying(prev->left);
else deleteByCopying(prev->right);
else if(node ==0)
cout <<"el "<<el<<" is not int the tree\n";
else cout<<"the tree is empty\n";
}
#endif // GENBST_H_INCLUDED
main.cpp
#include <iostream>
#include "genBST.h"
using namespace std;
int main()
{
BST<int> bst;
//插入
bst.insert(15);
bst.insert(10);
bst.insert(5);
bst.insert(11);
bst.insert(12);
bst.insert(30);
bst.insert(21);
bst.insert(40);
bst.insert(3);
bst.insert(4);
bst.insert(2);
//广度优先遍历
bst.breadthFirst();
cout<<"\n节点数:" <<bst.pointNum()<<endl;
cout <<"叶子数: "<<bst.leafNum()<<endl;
cout <<"右子节点数目:"<<bst.rightNum()<<endl;
cout<<"数的高度为: "<<bst.deep()<<endl;
if(bst.isBalance())
cout<<"树是平衡二叉树"<<endl;
else
cout<<"树不是平衡二叉树"<<endl;
if(bst.isComplate())
cout<<"树是完全二叉树"<<endl;
else
cout<<"树不是完全二叉树"<<endl;
if(bst.isBinarySort())
cout<<"树是二叉排序树"<<endl;
else
cout<<"树不是二叉排序树"<<endl;
cout<<endl;
//深度
//递归遍历
bst.preorder();
cout<<endl;
bst.inorder();
cout <<endl;
bst.postorder();
cout<<endl;
//非递归遍历
bst.iterativePreorder();
cout<<endl;
cout<<"非递归中序遍历:"<<endl;
bst.iterativeInorder();
cout<<endl;
bst.iterInorder();
cout<<endl;
bst.iterativePostorder();
cout<<endl;
//查找
if(bst.search(11))
cout << "the number is int the tree"<<endl;
else
cout<<"the number is not in the tree"<<endl;
//合并删除
bst.findAndDeleteByMerging(10);
bst.breadthFirst();
cout<<endl;
//复制删除
bst.findAndDeleteByCopying(30);
bst.breadthFirst();
cout<<endl;
cout<<"节点数:" <<bst.pointNum()<<endl;
cout <<"叶子数: "<<bst.leafNum()<<endl;
cout <<"右子节点数目:"<<bst.rightNum()<<endl;
cout<<"数的高度为: "<<bst.deep()<<endl;
if(bst.isBalance())
cout<<"树是平衡二叉树"<<endl;
else
cout<<"树不是平衡二叉树"<<endl;
if(bst.isComplate())
cout<<"树是完全二叉树"<<endl;
else
cout<<"树不是完全二叉树"<<endl;
if(bst.isBinarySort())
cout<<"树是二叉排序树"<<endl;
else
cout<<"树不是二叉排序树"<<endl;
//bst.makefree();
return 0;
}