遍历方式
良心推荐学习视频(前置知识)
1.球球大家去看啦,看过包会!!完美地讲解二叉树的前中后序遍历顺序,为后续的算法实现打下基础
小声bb ... 一遍看不懂就多看几次
递归遍历
递归递归,要递也要归(递归出口),只递不归就是耍流氓!!!
递归与迭代的时间复杂度差不多,但在空间复杂度上递归还要用栈存储参数返回值,有可能会造成栈溢出.
迭代遍历
重点:递归的深层原理就是利用栈
其实这里也有前置知识:
1.栈,要明白栈FILO(先进后出)的原理, 明白pop(),top(),push(),empty()可以执行什么操作
2.使用c/c++ 进行遍历时有可能会用到箭头表达式 '->'
请记住: 声明 int*p;
(*p).val == p->val
记忆:箭头运算符左侧的变量类型一定是指针型的
3.push_back()方法是vector的方法,用于向向量尾部添加元素
reverse(a.begin(),a.end())方法,用来反转容器
LeetCode---遍历二叉树
二叉树的遍历具体实现代码可能每个地方讲得不一样,但核心思想是一样的,所以最重要的是要理解,理解完了也要硬性记忆下,不然学得多了以后会忘掉.
ps.LeetCode已经把常用的STL标准库函数和数据结构都提前导入了,比如本题中的stack和vector都可以直接用.
1.前序遍历
题目:给你二叉树的根节点 root ,返回它节点值的 前序 遍历
输入:root = [1,null,2,3]
输出:[1,2,3]
/**递归法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;//将preorderTraversal函数的返回值保存在vector容器中
vector<int> preorderTraversal(TreeNode* root) {
if(root)
{
ans.push_back(root->val);//根节点的值
preorderTraversal(root->left);
preorderTraversal(root->right);
}
return ans;
}
};
/**使用栈遍历
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
TreeNode *p = root;//传参
while(p || !st.empty())//p一直指向每一次的根节点
{
if(p)//根节点非空
{
ans.push_back(p->val);
st.push(p);
p = p->left;
}
else{//左子树访问完毕,开始访问右子树
p = st.top();//获取栈顶元素
st.pop();//弹栈
p = p->right;
}
}
return ans;
}
};
/**迭代法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
//TreeNode *p = root;//传参
if(root)st.push(root);
while(!st.empty())
{
TreeNode*node = st.top();
if(node!=nullptr)
{
st.pop();
if(node->right)st.push(node->right);//右
if(node->left)st.push(node->left);//左
st.push(node);//中
st.push(nullptr);
}
else
{
st.pop();
node = st.top();
st.pop();
ans.push_back(node->val);
}
}
return ans;
}
};
2.中序遍历
题目: 给定一个二叉树的根节点 root ,返回它的 中序 遍历。
输入:root = [1,null,2,3]
输出:[1,3,2]
/**递归法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> inorderTraversal(TreeNode* root) {
if(root)
{
inorderTraversal(root->left);
ans.push_back(root->val);//根节点
inorderTraversal(root->right);
}
return ans;
}
};
/**栈的迭代
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int>ans;
stack<TreeNode*>st;
TreeNode* p = root;
while( p!=nullptr|| !st.empty())
{
if(p!=nullptr)
{
st.push(p);
p = p->left;
}
else{
p = st.top();
st.pop();
ans.push_back(p->val);
p = p->right;
}
}
return ans;
}
};
/**迭代法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
if(root !=nullptr) st.push(root);//如果根节点非空,则将根节点入栈
while(!st.empty())//若栈非空
{
TreeNode*node = st.top();node指向栈顶元素
if(node != nullptr)//若栈顶元素非空
{
st.pop();//弹出栈顶元素
if(node->right)st.push(node->right);//如果栈顶元素存在右孩子,则将右孩子入栈
st.push(node);//右孩子入栈后,再重新将栈顶元素压入栈内
st.push(nullptr);//向栈中压入一个空节点
if(node->left)st.push(node->left);//如果根节点有左孩子,将左孩子入栈
}else//如果栈顶元素为空--对应if语句块中的st.push(nullptr);步骤
{
st.pop();//弹出栈顶的nullptr
node = st.top();//将栈顶指针指向根节点
st.pop();//弹出新的栈顶元素(根节点)
ans.push_back(node->val);//将根节点的值存入结果向量中
}
}
return ans;//二叉树全部遍历完毕后返回结果向量
}
};
后序遍历
题目:给定一个二叉树,返回它的后序遍历。
示例:
输入: [1,null,2,3]
输出: [3,2,1]
/**递归法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> postorderTraversal(TreeNode* root) {
if(root)
{
postorderTraversal(root->left);
postorderTraversal(root->right);
ans.push_back(root->val);
}
return ans;
}
};
/**利用栈遍历
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
st.push(root);
TreeNode*p = root;
st.push(p);
while(!st.empty()||p!=nullptr)
{
if(p)
{
p = st.top();
st.pop();
ans.push_back(p->val);
}
else
{
st.push(p->left);
st.push(p->right);
}
}
reverse(ans.begin(),ans.end());//将结果翻转
return ans;
}
};
/**迭代法
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<int>ans;
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
if(root !=nullptr)
{
st.push(root);
}
while(!st.empty())
{
TreeNode* node = st.top();
if(node!=nullptr)
{
st.pop();
st.push(node);//中
st.push(nullptr);
if(node->right)st.push(node->right);//右
if(node->left)st.push(node->left);//左
}
else
{
st.pop();
node = st.top();
st.pop();
ans.push_back(node->val);
}
}
return ans;
}
};