zoukankan      html  css  js  c++  java
  • 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;
    
    }
    

      

  • 相关阅读:
    集合的一些操作总结
    字符串的操作
    python字典的操作总结
    python中的列表知识总结
    Python利用文件操作实现用户名的存储登入操作
    如何理解:城市的“信息化→智能化→智慧化”
    程序员必备技能-怎样快速接手一个项目
    程序员的职业规划
    只要 8 个步骤,学会这个 Docker 命令终极教程!
    使用GitLab实现CI/CD
  • 原文地址:https://www.cnblogs.com/liujw2114/p/10539495.html
Copyright © 2011-2022 走看看