二叉树操作(插入、删除、遍历(递归与非递归))

//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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值