• 【数据结构上机练习】7. 二叉树的简单操作(2)


    这次主要是用到二叉树的非递归遍历和层次遍历。孩子兄弟节点表示法保存树的结构。

    //============================================================================
    // Name        : 5.1.cpp
    // Author      : 
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    /**
     * [实验目的]
           验证树和森林的遍历算法。
    [实验内容及要求]
         定义左儿子—右兄弟链接存储的树类和森林类。
        实验验证如下算法的正确性、各种功能及指标:
       1)创建树和森林;
       2)树和森林的先根遍历的递归和迭代算法;
       3)树和森林的后根遍历的递归和迭代算法;
       4)树和森林的层次遍历算法。
     */
    #include <iostream>
    #include<stack>
    #include<queue>
    using namespace std;
    
    
    //借用二叉树的 存储方式来表示孩子兄弟节点的表示方法
    typedef struct BinTreeNode{
        char data;
        struct BinTreeNode * left,*right;
    }BinTreeNode;
    
    class BinTree{
    private:
        BinTreeNode *root;
    public:
        BinTree(){
            cout<<"输入要创建的树,空节点用#代替\n";
            root = creat();
    }
        BinTree(BinTreeNode & temp){
            root = &temp;
            temp.left = NULL;
            temp.right = NULL;
        }
        BinTreeNode * getRoot(){
            return root;
        }
        BinTreeNode * creat(){ //递归创建树
            char t;
            cin>>t;
            if(t=='#'){// #  stand for null
                return NULL;
            }
            else{
                BinTreeNode *r = new BinTreeNode;
                r->data = t;
                r->left = creat();
                r->right = creat();
                return r;
            }
        }
        void unPreOrder(void){    //先跟遍历的非递归方法
            BinTreeNode *t = root;
            stack <BinTreeNode*> s;
            cout<<"\n 非递归方法,先跟遍历:"<<endl;
            while(t!=NULL||!s.empty()){
                while(t!=NULL){
                    cout<<t->data<<" ";
                    s.push(t);
                    t = t-> left;
                }
                if(!s.empty()){
                    t = s.top();
                    s.pop();
                    t = t->right;
                }
            }
        }
        void unInOrder(){
            BinTreeNode *t = root;
            stack <BinTreeNode*> s;
            cout<<"\n 非递归方法,中跟遍历:"<<endl;
            while(t!=NULL||!s.empty()){
                while(t!=NULL){
                    s.push(t);
                    t=t->left;
                }
                if(!s.empty()){
                    t = s.top();
                    cout<<t->data <<" ";
                    s.pop();
                    t= t->right;
                }
            }
        }
        void unPostOrder(){
            /**
             * 要保证根结点在左孩子和右孩子访问之后才能访问,
             * 因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
             * 则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子都已被访问过了,
             * 则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,
             * 这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,
             * 左孩子和右孩子都在根结点前面被访问。
             *
             */
            cout<<"\n 非递归方法,后跟遍历:"<<endl;
            stack <BinTreeNode*> s;
            BinTreeNode *pre = NULL,*cur;
            s.push(root);
                while(!s.empty()){
                    cur = s.top();
                    if((cur->left==NULL&&cur->right==NULL)||
                            (pre!=NULL&&(pre==cur->left||pre==cur->right))){
                        cout<<cur->data<<" ";//如果当前结点没有孩子结点或者孩子节点都已被访问过
                        s.pop();
                        pre = cur;
                    }else{
                        if(cur->right!=NULL)
                            s.push(cur->right);
                        if(cur->left!=NULL)
                            s.push(cur->left);
                    }
            }
        }
        void LevelOrder(){   //层次遍历
            BinTreeNode *p ;
            queue <BinTreeNode*> q;
            cout<<"\n对应二叉树层次遍历"<<endl;
            if(root!=NULL)
                q.push(root);
            while(!q.empty()){
                p = q.front();
                q.pop();
                cout<<p->data<<" ";
                if(p->left!=NULL)
                    q.push(p->left);
                if(p->right!=NULL)
                    q.push(p->right);
            }
        }
        void TreeLevelOrder(){   //树层次遍历
            BinTreeNode *p ;
            queue <BinTreeNode*> q;
            cout<<"\n树的层次遍历"<<endl;
            if(root!=NULL)
                q.push(root);
            while(!q.empty()){
                p = q.front();
                q.pop();
                while(p!=NULL){
                    cout<<p->data<<" ";
                    if(p->left!=NULL)
                        q.push(p->left);
                    p = p->right;
                }
            }
        }
    };
    void preOrderTra(BinTreeNode *t){ //先跟遍历 -递归
            if(t){
                cout<<t->data<<" ";
                preOrderTra(t->left);
                preOrderTra(t->right);
            }
    }
    void midOrderTra(BinTreeNode *t){  //中跟遍历-递归
        if(t){
            midOrderTra(t->left);
            cout<<t->data<<" ";
            midOrderTra(t->right);
        }
    }
    void bacOrderTra(BinTreeNode *t){  //后跟遍历-递归
        if(t){
            bacOrderTra(t->left);
            bacOrderTra(t->right);
            cout<<t->data<<" ";
        }
    }
    
    
    int main() {
    
        // 测试数据 (教材87页图)   *+A##B##+*-C##D##E##F##
    
        // *ab##ck###deh##fj##g###
    
            BinTree mb;
            BinTreeNode *r = mb.getRoot();
    
            //递归遍历
            cout<<"先跟遍历-递归"<<endl;
            preOrderTra(r);
            cout<<"\n中跟遍历-递归"<<endl;
            midOrderTra(r);
            cout<<"\n后跟遍历-递归"<<endl;
            bacOrderTra(r);
    
            //下面几个是非递归遍历
            mb.unPreOrder();
            mb.unInOrder();
            mb.unPostOrder();
    
            mb.LevelOrder();// 二叉树层次遍历
            mb.TreeLevelOrder(); //对应树的层次遍历,不过顺序有问题,是层次
        return 0;
    }

    运行结果:

    转载文章请注明出处: http://www.cnblogs.com/menglei/
  • 相关阅读:
    1130 host '***' is not allowed to connect to this MySQL server
    签名时出错,未能对....ext签名。SignTool Error: No certificates...
    C# 进制转换(二进制、十六进制、十进制互转)
    在安装32位Oracle客户端组建的情况下以64位模式运行
    Vue中引入jQuery
    sql server数据库分离时,数据库右侧显示(单个用户)
    解决Typora图片显示问题
    Ruby日文手册翻译1
    Boost Graph Library 库小结1
    归并排序
  • 原文地址:https://www.cnblogs.com/menglei/p/2797746.html
Copyright © 2020-2023  润新知