zoukankan      html  css  js  c++  java
  • 数据结构之二叉树基础一

    
    
    #include <iostream>
    #include <cstring>
    #include <stack>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    using namespace std;
    
    
    struct BTNode
    {
        char data;
        struct BTNode *lchild;
        struct BTNode *rchild;
    };
    
    typedef struct BTNode BTNode;
    
    
    //先序建立
    //abc##de#g##f###
    BTNode* creat(BTNode* root)
    {
        char s;
        scanf("%c",&s);
        if(s=='#')
        {
            root=NULL;
        }
        else
        {
            root=new BTNode;
            root->data=s;
            root->lchild=creat(root->lchild);
            root->rchild=creat(root->rchild);
        }
        return root;
    }
    
    
    void destory(BTNode *root)
    {
        if(root)
        {
            destory(root->lchild);
            destory(root->rchild);
            delete root;
        }
    }
    
    
    void visit(BTNode *p)
    {
        if(p)
        {
            cout<<p->data<<' ';
        }
    }
    
    void preOrder(BTNode *p)
    {
        if(p)
        {
            visit(p);
            preOrder(p->lchild);
            preOrder(p->rchild);
        }
    }
    
    void inOrder(BTNode *p)
    {
        if(p)
        {
            inOrder(p->lchild);
            visit(p);
            inOrder(p->rchild);
        }
    }
    void postOrder(BTNode *p)
    {
        if(p)
        {
    
            postOrder(p->lchild);
            postOrder(p->rchild);
            visit(p);
        }
    }
    void levelOrder(BTNode *root)
    {
        if(root == NULL)
            return;
        vector<BTNode *> vec;
        vec.push_back(root);
        int cur = 0;
        int last = 1;
    
        while(cur < vec.size())
        {
            last = vec.size();
    
            while(cur < last)
            {
                visit(vec[cur]);
                if(vec[cur]->lchild != NULL)
                    vec.push_back(vec[cur]->lchild);
                if(vec[cur]->rchild != NULL)
                    vec.push_back(vec[cur]->rchild);
                ++cur;
            }
            cout<<endl;
        }
    }
    
    //计算叶子个数
    int countLeaves(BTNode*root)
    {
        if(!root->lchild&&!root->rchild)
        {
            return 1;
        }
        int cnt1=0,cnt2=0;
        if(root->lchild)
        {
            cnt1=countLeaves(root->lchild);
        }
        if(root->rchild)
        {
            cnt2=countLeaves(root->rchild);
        }
        return cnt1+cnt2;
    }
    
    //计算结点数
    int countNodes(BTNode *root)
    {
        if(root)
        {
            return 1+countNodes(root->lchild)+countNodes(root->rchild);
        }
        return 0;
    }
    
    
    //非递归遍历
    void preOrder_norecursive(BTNode *root)
    {
        stack<BTNode*> st;
        BTNode *p=root;
        while(p!=NULL||!st.empty())
        {
            while(p!=NULL)
            {
                visit(p);
                st.push(p);
                p=p->lchild;
            }
            if(!st.empty())
            {
                p=st.top();
                st.pop();
                p=p->rchild;
            }
        }
    }
    
    void inOrder_norecursive(BTNode *root)
    {
        stack<BTNode*> st;
        BTNode *p=root;
        while(p!=NULL||!st.empty())
        {
            while(p!=NULL)
            {
                st.push(p);
                p=p->lchild;
            }
            if(!st.empty())
            {
                p=st.top();
                visit(p);
                st.pop();
                p=p->rchild;
            }
        }
    }
    /*
    要保证根结点在左孩子和右孩子访问之后才能访问,
    因此对于任一结点P,先将其入栈。如果P不存在左孩子和右孩子,
    则可以直接访问它;或者P存在左孩子或者右孩子,
    但是其左孩子和右孩子都已被访问过了,则同样可以直接访问该结点。
    若非上述两种情况,则将P的右孩子和左孩子依次入栈,这样就保证了每次取栈顶元素的时候,
    左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
    */
    void postOrder_norecursive(BTNode *root)
    {
        stack<BTNode*> s;
        BTNode *cur;                      //当前结点
        BTNode *pre=NULL;                 //前一次访问的结点
        s.push(root);
        while(!s.empty())
        {
            cur=s.top();
            if((cur->lchild==NULL&&cur->rchild==NULL)||
                    (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
            {
                cout<<cur->data<<" ";  //如果当前结点没有孩子结点或者孩子节点都已被访问过
                s.pop();
                pre=cur;
            }
            else
            {
                if(cur->rchild!=NULL)
                    s.push(cur->rchild);
                if(cur->lchild!=NULL)
                    s.push(cur->lchild);
            }
        }
    }
    
    
    int main()
    {
        //abc##de#g##f###
        BTNode* root;
        root=creat(root);
        preOrder(root);
        cout<<endl;
        inOrder(root);
        cout<<endl;
        postOrder(root);
        cout<<endl;
        levelOrder(root);
        cout<<endl;
        cout<<"countNodes="<<countNodes(root)<<endl;
        cout<<"countLeaves="<<countLeaves(root)<<endl;
        preOrder_norecursive(root);
        cout<<endl;
        inOrder_norecursive(root);
        cout<<endl;
        postOrder_norecursive(root);
        cout<<endl;
    
        destory(root);
        return 0;
    }
    



  • 相关阅读:
    类的设计问题
    php数组存在重复的相反元素,去重复
    常用JS验证函数总结
    python常用模块
    re 模块
    logging 模块
    configparser模块
    python 文件处理
    第15章-输入/输出 --- 理解Java的IO流
    第10章-验证框架 --- 验证器类型
  • 原文地址:https://www.cnblogs.com/jasonhaven/p/7355040.html
Copyright © 2011-2022 走看看