二叉树模板及二叉树的无递归遍历

#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template <class T> class BinaryTree;
template <class T>
class BinaryTreeNode
{
    friend class BinaryTree<T>;
private:
    T data; //二叉树数据域
    BinaryTreeNode *leftchild; //左孩子指针
    BinaryTreeNode *rightchild; //右孩子指针
public:
    BinaryTreeNode(){leftchild=rightchild=NULL;}
    BinaryTreeNode(const T elem)
    {
        data=elem;
        leftchild=rightchild=NULL;
    }
    BinaryTreeNode(const T elem,BinaryTreeNode<T> *l,BinaryTreeNode<T> *r)
    {
        data=elem;
        leftchild=l;
        rightchild=r;
    }
    BinaryTreeNode<T> * left() const{return leftchild;}
    BinaryTreeNode<T> * right() const{return rightchild;}
    void setLeft(BinaryTreeNode *l){leftchild=l;}
    void setRight(BinaryTreeNode *r){rightchild=r;}
    void setValue(const T value){data=value;}
    T getValue(){return data;}
    bool isLeaf()
    {
        if(leftchild==NULL&&rightchild==NULL)
            return true;
        else
            return false;
    }
    BinaryTreeNode<T>& operator = (const BinaryTreeNode<T> &Node)
    {
        cout << "=" ;
        data=Node.data;
        leftchild=Node.leftchild;
        rightchild=Node.leftchild;
        return *this;
    }
};
template <class T>
class BinaryTree
{
private:
    BinaryTreeNode<T> *root;
public:
    BinaryTree(){root=NULL;}
    bool isEmpty() const
    {
        if(root==NULL)
            return true;
        return false;
    };
    BinaryTreeNode<T> * Root(){return root;}
    BinaryTreeNode<T> * Parent(BinaryTreeNode<T> *current);
    BinaryTreeNode<T> * LeftSibling(BinaryTreeNode<T> *current);
    BinaryTreeNode<T> * RightSibling(BinaryTreeNode<T> *current);
    void CreatTree(const T &info,BinaryTree<T> &left,BinaryTree<T> &right);
    void PreOrder(BinaryTreeNode<T> *root);
    void InOrder(BinaryTreeNode<T> *root);
    void PostOrder(BinaryTreeNode<T> *root);
    void LevelOrder(BinaryTreeNode<T> *root);
    void deleteBinaryTree(BinaryTreeNode<T> *root);
    void PreOrderWithoutRecursion(BinaryTreeNode<T> *root);
    void InOrderWithoutRecursion(BinaryTreeNode<T> *root);
    void PostOrderWithoutRecursion(BinaryTreeNode<T> *root);
};
template <class T>
class StackElem{
public:
    BinaryTreeNode<T> *pointer;
    int tag;
};
template <class T>
BinaryTreeNode<T> * BinaryTree<T>::Parent(BinaryTreeNode<T> *current) //返回当前结点的父结点
{
    using std::stack;
    stack<BinaryTreeNode<T> *> aStack; //使用栈存放未访问右子树的结点
    BinaryTreeNode<T> *pointer=root;
    if(root!=NULL&&current!=NULL)
    {
        while(!aStack.empty()||pointer!=NULL)
        {
            if(pointer!=NULL)
            {
                if(current==pointer->left()||current==pointer->right())
                    return pointer;
                aStack.push(pointer);
                pointer=pointer->left();
            }
            else
            {
                pointer=aStack.top();
                aStack.pop();
                pointer=pointer->right();
            }
        }
        return NULL;
    }
    else
        return NULL;
}
template <class T>
BinaryTreeNode<T> * BinaryTree<T>::LeftSibling(BinaryTreeNode<T> *current) //返回当前节点左兄弟
{
    using std::stack;
    stack<BinaryTreeNode<T> *>aStack;
    BinaryTreeNode<T> *pointer=root;
    if(root!=NULL&&current!=NULL)
    {
        while(!aStack.empty()||pointer!=NULL)
        {
            if(pointer!=NULL)
            {
                if(current==pointer->right()&&(pointer->left())!=NULL)
                    return pointer->left();
                aStack.push(pointer);
                aStack.pop();
                pointer=pointer->left();
            }
            else
            {
                pointer=aStack.top();
                aStack.pop();
                pointer=pointer->right();
            }
        }
        return NULL;
    }
    else
        return NULL;
}
template <class T>
BinaryTreeNode<T> * BinaryTree<T>::RightSibling(BinaryTreeNode<T> *current) //返回当前节点右兄弟
{
    using std::stack;
    stack<BinaryTreeNode<T> *>aStack;
    BinaryTreeNode<T> *pointer=root;
    if(root!=NULL&&current!=NULL)
    {
        while(!aStack.empty()||pointer!=NULL)
        {
            if(pointer!=NULL)
            {
                if(current==pointer->left()&&(pointer->right())!=NULL)
                    return pointer->right();
                aStack.push(pointer);
                aStack.pop();
                pointer=pointer->left();
            }
            else
            {
                pointer=aStack.top();
                aStack.pop();
                pointer=pointer->right();
            }
        }
        return NULL;
    }
    else
        return NULL;
}
template <class T>
void BinaryTree<T>::CreatTree(const T &info,BinaryTree<T> &left,BinaryTree<T> &right) //创建树
{
    root=new BinaryTreeNode<T>(info,left.root,right.root);
    left.root=right.root=NULL;
}
template <class T>
void BinaryTree<T>::PreOrder(BinaryTreeNode<T> *root) //先序遍历
{
    if(root!=NULL)
        visit(root);
    else
        return;
    PreOrder(root->left());
    PreOrder(root->right());
}
template <class T>
void BinaryTree<T>::InOrder(BinaryTreeNode<T> *root) //中序遍历
{
    if(root==NULL)
        return;
    InOrder(root->left());
    visit(root);
    InOrder(root->right());
}
template <class T>
void BinaryTree<T>::PostOrder(BinaryTreeNode<T> *root) //后序遍历
{
    if(root==NULL)
        return;
    PostOrder(root->left());
    PostOrder(root->right());
    visit(root);
}
template <class T>
void BinaryTree<T>::LevelOrder(BinaryTreeNode<T> *root) //层次遍历
{
    using std::queue;
    queue<BinaryTreeNode<T> *> aQueue;
    BinaryTreeNode<T> *p=root,*q;
    aQueue.push(p);
    while(!aQueue.empty())
    {
        p=aQueue.front();
        aQueue.pop();
        visit(p);
        q=p;
        if((p->left())!=NULL)
        {
            q=p->left();
            aQueue.push(q);
        }
        if((p->right())!=NULL)
        {
            q=p->right();
            aQueue.push(q);
        }
    }
}
template <class T>
void BinaryTree<T>::deleteBinaryTree(BinaryTreeNode<T> *root) //删除以root为根节点的树
{
    if(root==NULL)return;
    deleteBinaryTree(root->left());
    deleteBinaryTree(root->right());
    delete root;
    root=NULL;
}
template <class T>
void BinaryTree<T>::PreOrderWithoutRecursion(BinaryTreeNode<T> *root) //无递归先序遍历
{
    //先输出将当前结点,并将当前结点的右子树放入栈中,再访问左子树
    //无结点可访问时弹出栈顶元素
    using std::stack;
    stack<BinaryTreeNode<T> *>aStack;
    BinaryTreeNode<T> *pointer=root;
    aStack.push(NULL); //栈底监视哨
    while(pointer!=NULL)
    {
        visit(pointer);
        if((pointer->right())!=NULL)aStack.push(pointer->right());
        if((pointer->left())!=NULL)aStack.push(pointer->left()); //左子树压栈后马上就会被弹出
        pointer=aStack.top();
        aStack.pop();
    }
}
template <class T>
void BinaryTree<T>::InOrderWithoutRecursion(BinaryTreeNode<T> *root) //无递归中序遍历
{
    //遇到结点先入栈,无结点可访问时出栈
    using std::stack;
    stack<BinaryTreeNode<T> *>aStack;
    BinaryTreeNode<T> *pointer=root;
    while(!aStack.empty()||pointer!=NULL)
    {
        if(pointer!=NULL)
        {
            aStack.push(pointer);
            pointer=pointer->left();
        }
        else{
            pointer=aStack.top();
            aStack.pop();
            visit(pointer);
            pointer=pointer->right();
        }
    }
}
template <class T>
void BinaryTree<T>::PostOrderWithoutRecursion(BinaryTreeNode<T> *root) //无递归中序遍历
{
    //遇到结点打标记,出栈时如果是右子树已访问则访问结点,否则继续入栈
    using std::stack;
    StackElem<T> elem;
    stack<StackElem<T> > aStack;
    BinaryTreeNode<T> *pointer;
    if(root==NULL)return;
    else pointer=root;
    while(!aStack.empty()||pointer!=NULL)
    {
        while(pointer!=NULL)
        {
            elem.pointer=pointer;
            elem.tag=1;
            aStack.push(elem);
            pointer=pointer->left();
        }
        elem=aStack.top();
        aStack.pop();
        pointer=elem.pointer;
        if(elem.tag)
        {
            elem.tag=0;
            aStack.push(elem);
            pointer=pointer->right();
        }
        else
        {
            visit(pointer);
            pointer=NULL;
        }
    }
}
void dCreat(BinaryTree<int> &t) //先序递归建树
{
    BinaryTree<int> l,r;
    int a;
    cin>>a;
    if(a==0) //输入0认为当前结点为空
    {
        return;
    }
    dCreat(l);
    dCreat(r);
    t.CreatTree(a,l,r);
}
void visit(BinaryTreeNode<int> *Root) //访问结点元素
{
    if(Root!=NULL)
        cout << Root->getValue() <<" ";
}
int main()
{
    BinaryTreeNode<int> *d;
    BinaryTreeNode<int> e(10);
    BinaryTree<int> a,b,c;
    int n,s,l=1;
    cin >>n;
    while((n--)>0)
    {
        dCreat(a);
        cout << "PreOrder:";
        a.PreOrder(a.Root());
        cout <<endl;
        cout << "PreOrderWithoutRecursion:";
        a.PreOrderWithoutRecursion(a.Root());
        cout <<endl;
        cout <<"InOrder:";
        a.InOrder(a.Root());
        cout <<endl;
        cout <<"InOrderWithoutRecursion:";
        a.InOrderWithoutRecursion(a.Root());
        cout <<endl;
        cout <<"PostOrder:";
        a.PostOrder(a.Root());
        cout <<endl;
        cout <<"PostOrderWithoutRecursion:";
        a.PostOrderWithoutRecursion(a.Root());
        cout <<endl;
        cout <<"LevelOrder:";
        a.LevelOrder(a.Root());
        cout<<endl;
        d=a.Root();
        d=d->left();
        d=a.Parent(d);
        visit(d);
        cout <<endl;
        d=d->left();
        d=a.RightSibling(d);
        visit(d);
        d=a.Root();
        cout <<endl;
        d=a.LeftSibling(d->right());
        visit(d);
        d=a.Parent(a.Root());
        visit(d);
        cout <<endl;
        a.deleteBinaryTree(a.Root());
    }
    return 0;
}
/*
2
5 1 2 0 0 3 0 0 0
5 1 2 0 0 3 0 0 4 0 0
*/
/*
样例树:
    5
   /
  1
 / \
2   3


    5
   / \
  1   4
 / \
2   3
*/

 

posted @ 2018-05-11 07:58  LowBee  阅读(251)  评论(0编辑  收藏  举报