C++二叉树实现

#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template <class T>
class BinTreeNode
{
private:
    T data;
    BinTreeNode<T> *left;
    BinTreeNode<T> *right;
public:
    BinTreeNode(const T& dt=NULL,BinTreeNode<T> *l=NULL,BinTreeNode<T> *r=NULL):data(dt),left(l),right(r) {};
    BinTreeNode<T> * GetLeft(void)const
    {
        return left;
    }
    BinTreeNode<T> * GetRight(void)const
    {
        return right;
    }
    T GetData()const
    {
        return data;
    }
    void SetLeft(BinTreeNode<T>* l)
    {
        left=l;   ///此处赋值,非构造函数
    }
    void SetRight(BinTreeNode<T>* r)
    {
        right=r;
    }
    void SetData(const T& dt)
    {
        data=dt;
    }
};
template <class T>
class BinTree
{
private:
    BinTreeNode<T> *root;
    T stop;///构造二叉树时的输入结束符
    int index=-1;///使用数组构造二叉树时用于遍历数组元素
public:
    BinTree(BinTreeNode<T>* rt=NULL):root(rt) {};
    virtual ~BinTree()
    {
        Del(root);
    }
    ///二叉树的创建,通过io输入创建与通过数组创建,均为先序
    BinTreeNode<T>* Create();
    BinTreeNode<T>* CreateFromArr(T*a);
    ///节点删除
    void DelSubtree(BinTreeNode<T>* t);///从树中删除结点t及其左右子树
    void Del(BinTreeNode<T>* t);///删除结点t及其左右子树
    ///递归前中后序遍历
    void PreOrder(BinTreeNode<T>* t)const;
    void InOrder(BinTreeNode<T>* t)const;
    void PostOrder(BinTreeNode<T>* t)const;
    ///非递归前中后续遍历
    void NorecPreOrder()const;
    void NorecInOrder()const;
    void NorecPostOrder()const;
    ///其他操作
    BinTreeNode<T>* GetRoot() const
    {
        return root;
    }
    void SetRoot(BinTreeNode<T>* t)
    {
        root=t;
    }
    T GetStop()const
    {
        return stop;
    }
    void SetStop(const T& s)
    {
        stop=s;
    }
    bool IsEmpty()const
    {
        return root==NULL;
    }
};
///从数组创建一个二叉树
template <class T>
BinTreeNode<T>* BinTree<T>::CreateFromArr(T* a)
{
    BinTreeNode<T>* root = NULL;
    //cout<<index<<">>>"<<a[index]<<endl;
    index++;
    if (a[index] != stop)
    {
        root = new BinTreeNode<T>(a[index]);
        root->SetLeft(CreateFromArr(a));
        root->SetRight(CreateFromArr(a));

    }
    return root;
}
///由io流创建一个二叉树
template <class T>
BinTreeNode<T>* BinTree<T>::Create()
{
    BinTreeNode<T>* t,*t1,*t2;
    T item;
    cin>>item;
    ///递归出口
    if(item==stop)
    {
        t=NULL;
        return t;
    }
    ///先续构造二叉树
    else
    {
        t=new BinTreeNode<T>(item,NULL,NULL);
        t1=Create();
        t->SetLeft(t1);
        t2=Create();
        t->SetRight(t2);
        return t;
    }
}
///递归遍历
template <class T>
void BinTree<T>::Del(BinTreeNode<T> *t)
{
    if(t!=NULL)
    {
        Del(t->GetLeft());
        Del(t->GetRight());
        delete t;
    }
}
template <class T>
void BinTree<T>::PreOrder(BinTreeNode<T>* t)const
{
    if(t!=NULL)
    {
        cout<<t->GetData()<<"->";
        PreOrder(t->GetLeft());
        PreOrder(t->GetRight());
    }
}
template <class T>
void BinTree<T>::PostOrder(BinTreeNode<T>* t)const
{
    if(t!=NULL)
    {
        PostOrder(t->GetLeft());
        PostOrder(t->GetRight());
        cout<<t->GetData()<<"->";
    }
}
template <class T>
void BinTree<T>::InOrder(BinTreeNode<T>* t)const
{
    if(t!=NULL)
    {
        InOrder(t->GetLeft());
        cout<<t->GetData()<<"->";
        InOrder(t->GetRight());
    }
}

///非递归遍历
template <class T>
void BinTree<T>::NorecPreOrder()const
{
    BinTreeNode<T> *p=root;
    stack<BinTreeNode<T>*> s;
    while(p||!s.empty())
    {
        if(p)
        {
            cout<<p->GetData()<<"->";
            s.push(p);
            p=p->GetLeft();
        }
        else
        {
            p=s.top();
            s.pop();
            p=p->GetRight();
        }
    }
    return;
}


template <class T>
void BinTree<T>::NorecInOrder() const
{
    stack<BinTreeNode<T>*> s;
    BinTreeNode<T> *p=root;
    while(p||!s.empty())
    {
        if(p)
        {
            s.push(p);
            p=p->GetLeft();
        }
        else
        {

            p=s.top();
            cout<<p->GetData()<<"->";
            s.pop();
            p=p->GetRight();
        }
    }
    return;
}

///后序遍历:这是三种遍历方法中最为复杂的一种,
///因为它的根节点是最后访问的,在我们出栈遇到该节点时,
///我们并不知道此时它的右子树是否被访问过,
///所以我们需要额外借助一个节点变量用来判断右子树的访问真值。
template <class T>
void BinTree<T>::NorecPostOrder() const
{
    BinTreeNode<T> *p=root,*temp=NULL;
    stack<BinTreeNode<T> *>s;
    while(p||!s.empty())///只有p为空切栈为空时,退出循环
    {
        if(p)
        {
            s.push(p);
            p=p->GetLeft();
        }
        else
        {
            p=s.top();
            ///p的右子树非空且p的右子树不为temp(标志节点)
            ///此时p的右子树还未遍历过
            if(p->GetRight()&&p->GetRight()!=temp)
            {
                p=p->GetRight();
                s.push(p);
                p=p->GetLeft();
            }
            ///当右子树已经遍历过时或右子树为空,此时应该进行节点的输出
            else
            {
                s.pop();
                cout<<p->GetData()<<"->";
                temp=p;
                p=NULL;
            }
        }
    }
    return;
}

int main()
{
    char arr[]= {'A','B','D','#','G','#','#','E','#','#','C','F','#','#','#'};
    /*
                              A                       Pre :ABDGECF
                          /       \                   In  :DGBEAFC
                        B          C                  Post:GDEBFCA
                      /   \       /  \
                    D      E     F    #
                   / \    / \   / \
                  #   G  #   # #   #
                     / \
                    #   #
     */
    BinTree<char> *tree=new BinTree<char>;
    tree->SetStop('#');
    cout<<"CreatTheTree"<<endl;
    ///由io流创建
    ///BinTreeNode<char> *rt=tree->Create();
    ///由数组创建
    BinTreeNode<char> *rt=tree->CreateFromArr(arr);
    tree->SetRoot(rt);
    cout<<endl;

    cout<<"PreOrder>>>";
    tree->PreOrder(tree->GetRoot());
    cout<<endl;

    cout<<"InOrder>>>";
    tree->InOrder(tree->GetRoot());
    cout<<endl;

    cout<<"PostOrder>>>";
    tree->PostOrder(tree->GetRoot());
    cout<<endl;

    cout<<"NorecPreOrder>>>";
    tree->NorecPreOrder();
    cout<<endl;

    cout<<"NorecInOrder>>>";
    tree->NorecInOrder();
    cout<<endl;

    cout<<"NorecPostOrder>>>";
    tree->NorecPostOrder();
    cout<<endl;

}

  

posted @ 2019-03-15 21:01  大大维  阅读(143)  评论(0编辑  收藏  举报