zoukankan      html  css  js  c++  java
  • 【面试】二叉树遍历的非递归实现


    面试时,一般都会对二叉树进行考察,其中二叉树遍历的非递归方法经常会被面试官提到(因为递归方法太简单了,有时不懂也可以写出来),本文主要讲二叉树遍历的非递归方法(过段时间会整理出来一个关于二叉树面试的专题,本文将作为其中的一部分)。


     1. 二叉树遍历的非递归实现

    void Bst::preOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        BstNode* pCur = root;
        stack<BstNode*> s;
        while(pCur || !s.empty()){
            while(pCur){
                s.push(pCur);
                cout<<pCur->val<<" ";
                pCur = pCur->left;
            }
            if(!s.empty()){
                pCur = s.top();
                s.pop();
                pCur = pCur->right;
            }
        }
    }
    
    void Bst::inOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        stack<BstNode*> s;
        BstNode* pCur = root;
        while(pCur || !s.empty()){
            while(pCur){
                s.push(pCur);
                pCur = pCur->left;
            }
            if(!s.empty()){
                pCur = s.top();
                cout<<pCur->val<<" ";
                s.pop();
                pCur = pCur->right;
            }
        }
    }
    
    void Bst::postOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        stack<BstNode*> s;
        BstNode* pCur = root;
        BstNode* pLast = NULL;
    
        while(pCur){
            s.push(pCur);
            pCur = pCur->left;
        }
    
        while(!s.empty()){
            pCur = s.top();
            s.pop();
            if(pCur->right == NULL || pCur->right == pLast){
                cout<<pCur->val<<" ";
                pLast = pCur;
            }
            else if(pCur->left == pLast){
                s.push(pCur);
                pCur = pCur->right;
                while(pCur){
                    s.push(pCur);
                    pCur = pCur->left;
                }
            }
        }
    }

    2. 完整测试代码(可直接运行)

    /*
    * @Author: z.c.wang
    * @Email:  iwangzhengchao@gmail.com
    * @Date:   2018-10-12 21:08:15
    * @Last Modified time: 2019-03-16 17:20:31
    */
    
    #include<iostream>
    #include<vector>
    #include<stack>
    #include<algorithm>
    using namespace std;
    
    class BstNode {
    public:
        int val;
        BstNode* left;
        BstNode* right;
        BstNode(int x):
            val(x), left(NULL), right(NULL){};
    };
    
    class Bst{
    public:
        BstNode *root;
        Bst():
            root(NULL){}
    
        void insert(int value);
        void preOrder(BstNode* root);
        void inOrder(BstNode* root);
        void postOrder(BstNode* root);
        void preOrderWithoutRecursion(BstNode* root);
        void inOrderWithoutRecursion(BstNode* root);
        void postOrderWithoutRecursion(BstNode* root);
    };
    
    
    void Bst::insert(int value){
        BstNode* pRoot = root;
        // 空树
        if(pRoot == NULL)
            root = new BstNode(value);
        // 非空
        else{
            BstNode* temp;
            while(pRoot!= NULL && pRoot->val!=value){
                temp = pRoot;
                if(pRoot->val > value)
                    pRoot = pRoot->left;
                else
                    pRoot = pRoot->right;
            }
            pRoot = temp;
            if(pRoot->val > value)
                pRoot->left = new BstNode(value);
            else
                pRoot->right = new BstNode(value);
        }
        cout<<"the value "<<value<<" is inserted."<<endl;
    }
    
    
    void Bst::inOrder(BstNode* root){
        if(root == NULL)
            return ;
        inOrder(root->left);
        cout<<root->val<<" ";
        inOrder(root->right);
    }
    
    void Bst::preOrder(BstNode* root){
        if(root == NULL)
            return ;
        cout<<root->val<<" ";
        preOrder(root->left);
        preOrder(root->right);
    }
    
    void Bst::postOrder(BstNode* root){
        if(root == NULL)
            return ;
        postOrder(root->left);
        postOrder(root->right);
        cout<<root->val<<" ";
    }
    
    void Bst::preOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        BstNode* pCur = root;
        stack<BstNode*> s;
        while(pCur || !s.empty()){
            while(pCur){
                s.push(pCur);
                cout<<pCur->val<<" ";
                pCur = pCur->left;
            }
            if(!s.empty()){
                pCur = s.top();
                s.pop();
                pCur = pCur->right;
            }
        }
    }
    
    void Bst::inOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        stack<BstNode*> s;
        BstNode* pCur = root;
        while(pCur || !s.empty()){
            while(pCur){
                s.push(pCur);
                pCur = pCur->left;
            }
            if(!s.empty()){
                pCur = s.top();
                cout<<pCur->val<<" ";
                s.pop();
                pCur = pCur->right;
            }
        }
    }
    
    void Bst::postOrderWithoutRecursion(BstNode* root){
        if(root == NULL)
            return ;
        stack<BstNode*> s;
        BstNode* pCur = root;
        BstNode* pLast = NULL;
    
        while(pCur){
            s.push(pCur);
            pCur = pCur->left;
        }
    
        while(!s.empty()){
            pCur = s.top();
            s.pop();
            if(pCur->right == NULL || pCur->right == pLast){
                cout<<pCur->val<<" ";
                pLast = pCur;
            }
            else if(pCur->left == pLast){
                s.push(pCur);
                pCur = pCur->right;
                while(pCur){
                    s.push(pCur);
                    pCur = pCur->left;
                }
            }
        }
    }
    
    
    int main(int argc, char const *argv[])
    {
        Bst tree;
        int arr[] = {62, 58, 47, 35, 29,
                     37, 36, 51, 49, 48,
                     50, 56, 88, 73, 99, 93};
        for(int i=0; i<16; i++)
            tree.insert(arr[i]);
        cout<<endl<<"前序遍历: ";
        tree.preOrder(tree.root);
        cout<<endl<<"前序遍历: ";
        tree.preOrderWithoutRecursion(tree.root);
    
        cout<<endl<<"中序遍历: ";
        tree.inOrder(tree.root);
        cout<<endl<<"中序遍历: ";
        tree.inOrderWithoutRecursion(tree.root);
    
        cout<<endl<<"后序遍历: ";
        tree.postOrder(tree.root);
        cout<<endl<<"后序遍历: ";
        tree.postOrderWithoutRecursion(tree.root);
        return 0;
    }

    3. 测试结果

    (运行结果中的第一个表示递归方法,第二个表示非递归方法,可见结果相同)

    the value 62 is inserted.
    the value 58 is inserted.
    the value 47 is inserted.
    the value 35 is inserted.
    the value 29 is inserted.
    the value 37 is inserted.
    the value 36 is inserted.
    the value 51 is inserted.
    the value 49 is inserted.
    the value 48 is inserted.
    the value 50 is inserted.
    the value 56 is inserted.
    the value 88 is inserted.
    the value 73 is inserted.
    the value 99 is inserted.
    the value 93 is inserted.
    
    前序遍历: 62 58 47 35 29 37 36 51 49 48 50 56 88 73 99 93 
    前序遍历: 62 58 47 35 29 37 36 51 49 48 50 56 88 73 99 93 
    中序遍历: 29 35 36 37 47 48 49 50 51 56 58 62 73 88 93 99 
    中序遍历: 29 35 36 37 47 48 49 50 51 56 58 62 73 88 93 99 
    后序遍历: 29 36 37 35 48 50 49 56 51 47 58 73 93 99 88 62 
    后序遍历: 29 36 37 35 48 50 49 56 51 47 58 73 93 99 88 62
  • 相关阅读:
    视频实例分割 | Target-Aware Adaptive Tracking for Unsupervised Video Object Segmentation
    目标检测算法:Selective Search(选择性搜索)简述
    [2020BUAA软工助教]期末总结
    WPF,数据验证方案,验证通过才能继续下一步
    WPF:解决数据验证ValidationRule与按钮Canexcute联动的问题
    解决mininet运行报错“ImportError: No module named mininet.log”
    交易所对接ERC20钱包端口要多长时间?
    尺子的刻度
    学习java的第四周
    学习java的第三周
  • 原文地址:https://www.cnblogs.com/iwangzhengchao/p/10543233.html
Copyright © 2011-2022 走看看