zoukankan      html  css  js  c++  java
  • [数据结构]二叉树遍历的递归非递归实现(前序、中序、后序、层次)

    前序

    前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。
    给定一个二叉树,返回它的 前序遍历。
    示例:

    输入: [1,null,2,3]  
    
           1
            
             2
            /
           3 
           
    输出: [1,2,3]
    

    进阶: 递归算法很简单,你可以通过迭代算法完成吗?

    递归

    vector res需要在方法外声明**

    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
    public:
        vector<int> res;
        vector<int> preorderTraversal(TreeNode* root) {
    	
    	if (root != NULL)
    	{
    		res.push_back(root->val);
    		if(root->left!=NULL)
    			preorderTraversal(root->left);
    		if (root->right != NULL)
    			preorderTraversal(root->right);
    	}
    	return res;
    }
    };
    

    非递归

    思路:
    利用堆栈来实现,对于任何一个节点可以看为是根节点,直接访问,随后依次将右孩子和左孩子入栈
    循环结束的条件是栈为空

    vector<int> preorderTraversal(TreeNode* root) {
        stack<TreeNode*> nodestack;
        vector<int> res;
        if(root==NULL)
            return res;
        else
        {
            nodestack.push(root);
            while(nodestack.empty()==false)
            {
                TreeNode* temp=nodestack.top();
                res.push_back(temp->val);
                nodestack.pop();
                if(temp->right!=NULL)
                    nodestack.push(temp->right);
                if(temp->left!=NULL)
                    nodestack.push(temp->left);
            }
            return res;
        }
    }
    

    中序

    中序遍历按照“左孩子-根结点-右孩子”的顺序进行访问。

    递归

    vector<int> res;
    vector<int> inorderTraversal(TreeNode* root) {
        if(root==NULL)
            return res;
        inorderTraversal(root->left);
        res.push_back(root->val);
        inorderTraversal(root->right);
        return res;
    }
    

    非递归

    思路:
    当前节点入栈,随后当前节点为其左孩子节点,循环往复直到没有左孩子。随后访问栈顶元素,并将当前节点设置为其右孩子节点,按照同样的规则对右子树进行访问
    遍历结束条件:栈空且当前节点为NULL

    vector<int> inorderTraversal(TreeNode* root) {
         stack<TreeNode*> st;
         vector<int> res;
         if(root==NULL)
             return res;
         TreeNode* pn=root;
         while(st.empty()==false||pn!=NULL)
         {
             while(pn!=NULL)
             {
                 st.push(pn);  
                 pn=pn->left;
             }
             pn=st.top();
             res.push_back(pn->val);
             st.pop();
             if(pn->right!=NULL)
                 pn=pn->right;
             else
                 pn=NULL;
         }
         return res;
    }
    

    后序

    后序遍历按照“左孩子-右孩子-根结点”的顺序进行访问。

    递归

    递归实现
    vector<int> res;
    vector<int> postorderTraversal(TreeNode* root) {
        if(root==NULL)
            return res;
        else
        {
            postorderTraversal(root->left);
            postorderTraversal(root->right);
            res.push_back(root->val);
        }
        return res;
    }
    

    非递归

    思路:
    增加一个指针pre用以记录上一个访问的节点
    对于栈顶的节点如果他没有左右孩子,或者他的左右孩子已经被访问过了则可以直接访问他 (即比较pre和节点左右孩子)
    否则依次将他的右孩子、左孩子压栈

    vector<int> postorderTraversal(TreeNode* root) {
    	stack<TreeNode*> st;
    	TreeNode* curr=root;
    	TreeNode*  pre=NULL;
    	vector<int> res;
    	if (root != NULL)
    	{
    		st.push(root);
    		while (!st.empty())
    		{
    			curr = st.top();
    			if ((curr->left == NULL&&curr->right == NULL) ||
    				(pre != NULL && (pre == curr->left || pre == curr->right))
    				)
    			{
    				st.pop();
    				res.push_back(curr->val);
    				pre = curr;
    			}
    			else
    			{
    				if (curr->right != NULL)
    					st.push(curr->right);
    				if (curr->left != NULL)
    					st.push(curr->left);
    			}
    		}
    	}
    	return res;
    }
    

    层次

    非递归

    思路:
    通过队列来实现,每当访问一个节点,节点出栈的同时依次把它的左孩子、右孩子压栈。
    循环终止的条件为队列为空
    内部循环用以分层次访问,循环开始前记录队列长度,即当前层次的节点数

    vector<vector<int>> levelOrder(TreeNode* root) {
    	vector<vector<int>> result;
    	queue<TreeNode*> nodequeue;
    	if (root==NULL)
    	{
    		return result;
    	}
    	nodequeue.push(root);
    	while (!nodequeue.empty())
    	{
    		int count = nodequeue.size();
    		vector<int> levelresult;
    		while (count--)
    		{
    			TreeNode* temp = nodequeue.front();
    			nodequeue.pop();
    			levelresult.push_back(temp->val);
    			if (temp->left) nodequeue.push(temp->left);
    			if (temp->right) nodequeue.push(temp->right);
    		}
    		result.push_back(levelresult);
    	}
    	return result;
    }
    
  • 相关阅读:
    使用java Graphics 绘图工具生成顺丰快递电子面单
    NPM使用命令总结
    MYSQL主从库同步配置过程
    Redis的事务功能详解
    MapReduce 原理与 Python 实践
    Django权限机制的实现
    Python调用外部程序——os.system()和subprocess.call
    oracle11g安装教程(注意事项及图文教程)
    顶级的JavaScript框架、库、工具及其使用
    经典CSS坑:如何完美实现垂直水平居中?
  • 原文地址:https://www.cnblogs.com/wendyy/p/9324110.html
Copyright © 2011-2022 走看看