前序
前序遍历按照“根结点-左孩子-右孩子”的顺序进行访问。
给定一个二叉树,返回它的 前序遍历。
示例:
输入: [1,null,2,3]
1
2
/
3
输出: [1,2,3]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?
递归
vector
/**
* 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;
}