二叉树的几种遍历的方法(后序遍历的另外一种递归实现还需要思考)
2017-01-10 16:57
736 查看
二叉树的几种遍历方法的非递归实现方式都采用的是栈来实现的,需要注意
Given a binary tree, return the inorder traversal
of its nodes' values.
For example:
Given binary tree
return
(1)非递归的方法,时间空间复杂度均为O(n)
(2)非递归的方法
(3)递归的方法
2、先序遍历:144. Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree
return
(1)递归的方法
(2)非递归的方法
3、后序遍历:145. Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree
return
Note: Recursive solution is trivial, could you do it iteratively?
(1)递归的方法
(2)非递归的方法
代码一、有序前序遍历时NLR,后序遍历时LRN,则可更改前序遍历,将前序遍历改为NRL,然后可将得到的改变后的前序遍历NRL的结果进行逆序就可以
得到后序遍历LRN
代码二、
前序后序中序遍历都会用到栈这个结构,这也是由树这种数据结构的特点决定的。比较特殊的是,后序遍历的顺序是"左子树->右子树->根",
它要求左子树和右子树都在根之前输出。根据这个特点,可以这样来进行,每次记录一个pre和cur,cur表示当前节点,pre表示上次输出的
节点(是上次输出的节点,不是上次访问的节点),如果pre正好是cur的左子树或者右子树,那么就可以输出cur,否则,说明还有cur的左子树
或者右子树等待输出,也就是还没到cur输出的时候。这是第一个可以让cur输出的条件。另外可以可以让cur输出的条件是,cur是叶子节点。
1、中序遍历:94. Binary Tree Inorder Traversal
Given a binary tree, return the inorder traversalof its nodes' values.
For example:
Given binary tree
[1,null,2,3],
1 \ 2 / 3
return
[1,3,2].
(1)非递归的方法,时间空间复杂度均为O(n)
vector<int> inorderTraversal(TreeNode* root) { if(NULL == root) return vector<int>(); vector<int> result; stack<TreeNode*> visitStk; TreeNode* curNode = root; while(curNode || !visitStk.empty()) { if(curNode) { visitStk.push(curNode); curNode = curNode->left; } else { curNode = visitStk.top(); visitStk.pop(); result.push_back(curNode->val); curNode = curNode->right; } } return result; }
(2)非递归的方法
(3)递归的方法
vector<int> inorderTraversal(TreeNode* root) { vector<int> result; inorderTraversal(root,result); return result; } void inorderTraversal(TreeNode* root,vector<int> &result) { if(root) { inorderTraversal(root->left,result); result.push_back(root->val); inorderTraversal(root->right,result); } }
2、先序遍历:144. Binary Tree Preorder Traversal
Given a binary tree, return the preorder traversal of its nodes' values.
For example:
Given binary tree
{1,#,2,3},
1 \ 2 / 3
return
[1,2,3].
(1)递归的方法
vector<int> preorderTraversal(TreeNode* root) { vector<int> result; preorderTraversal(root,result); return result; } void preorderTraversal(TreeNode* root, vector<int> &result) { if(root) { result.push_back(root->val); preorderTraversal(root->left,result); preorderTraversal(root->right,result); } }
(2)非递归的方法
vector<int> preorderTraversal(TreeNode* root) { if(root == NULL) return vector<int>(); vector<int> result; stack<TreeNode*> sta; sta.push(root); while(!sta.empty()) { TreeNode* temp = sta.top(); sta.pop(); result.push_back(temp->val); if(temp->right != NULL) sta.push(temp->right); if(temp->left !=NULL) sta.push(temp->left); } return result; }
3、后序遍历:145. Binary Tree Postorder Traversal
Given a binary tree, return the postorder traversal of its nodes' values.
For example:
Given binary tree
{1,#,2,3},
1 \ 2 / 3
return
[3,2,1].
Note: Recursive solution is trivial, could you do it iteratively?
(1)递归的方法
void postorderTraversal(TreeNode* root, vector<int> &result) { if(root) { postorderTraversal(root->left,result); postorderTraversal(root->right,result); result.push_back(root->val); } } vector<int> postorderTraversal(TreeNode* root) { vector<int> result; postorderTraversal(root,result); return result; }
(2)非递归的方法
代码一、有序前序遍历时NLR,后序遍历时LRN,则可更改前序遍历,将前序遍历改为NRL,然后可将得到的改变后的前序遍历NRL的结果进行逆序就可以
得到后序遍历LRN
vector<int> postorderTraversal(TreeNode* root) { if(NULL == root) return vector<int>(); stack<TreeNode*> sta; sta.push(root); vector<int> result; while(!sta.empty()) { TreeNode* temp = sta.top(); result.push_back(temp->val);//将当前的节点压进栈,并打印 sta.pop(); if(temp->left != NULL)//将当前节点的左孩子压进栈 sta.push(temp->left); if(temp->right != NULL)//将当前节点的右孩子压进栈 sta.push(temp->right); } reverse(result.begin(),result.end());//倒置即可得到最后的结果 return result; }
代码二、
前序后序中序遍历都会用到栈这个结构,这也是由树这种数据结构的特点决定的。比较特殊的是,后序遍历的顺序是"左子树->右子树->根",
它要求左子树和右子树都在根之前输出。根据这个特点,可以这样来进行,每次记录一个pre和cur,cur表示当前节点,pre表示上次输出的
节点(是上次输出的节点,不是上次访问的节点),如果pre正好是cur的左子树或者右子树,那么就可以输出cur,否则,说明还有cur的左子树
或者右子树等待输出,也就是还没到cur输出的时候。这是第一个可以让cur输出的条件。另外可以可以让cur输出的条件是,cur是叶子节点。
vector<int> postorderTraversal(TreeNode* root) { if(NULL == root) return vector<int>(); stack<TreeNode*> sta; sta.push(root); TreeNode* pre = NULL; vector<int> result; while(!sta.empty()) { TreeNode* temp = sta.top(); if((temp->left == NULL && temp->right == NULL)||((pre!=NULL)&&(pre==temp->left||pre==temp->right))) { result.push_back(temp->val); sta.pop(); pre = temp;//注意这里,pre仅仅在输出了cur的时候下才更新。 } else { if(temp->right != NULL) sta.push(temp->right); if(temp->left != NULL) sta.push(temp->left); } } return result; }
相关文章推荐
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 二叉树的几种遍历方法及递归和非递归的实现
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 数据结构 分别用递归和非递归方法实现二叉树先序,中序,后序遍历
- Java实现二叉树的前序、中序、后序、层序遍历(非递归方法)
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- 用c语言创建一颗二叉树,用递归方法实现对其进行先序、中序和后序遍历的操作。
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果
- Java实现二叉树的前序、中序、后序、层序遍历(递归方法)
- Java实现二叉树的前序、中序、后序遍历(递归方法)
- Java实现二叉树的前序、中序、后序遍历(非递归方法)
- c++实现二叉树的先序遍历,中序遍历,后序遍历(递归方法)及运行实例结果