一,深度优先
1.1,递归迭代
第一:确定递归函数的参数和返回值
第二:确定终止条件
第三:确定单层递归逻辑
第一:以前序为例:需要写入到vector里面进行打印,所以递归参数一定有vector,还有节点
void travesal(TreeNode*root,vector<int>v1)
第二:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要要结束了,所以如果当前遍历的这个节点是空,就直接return,代码如下:
if(root==nullptr)return ;
第三:前序就是中左右,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:
v1.push_back(root->val); // 中
traversal(root->left, v1); // 左
traversal(root->right, v1); // 右
看总体代码:
class Solution {
public:
void _preorderTraversal(TreeNode* root,vector<int>&v1)
{
if(root==nullptr)return;
v1.push_back(root->val);
_preorderTraversal(root->left,v1);
_preorderTraversal(root->right,v1);
}
vector<int> preorderTraversal(TreeNode* root)
{
vector<int>v1;
_preorderTraversal(root,v1);
return v1;
}
};
其后序与中序遍历只需调节一下单层递归的逻辑即可
1.2 迭代遍历
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
前序遍历是:左---中---右,但我们在使用栈实现遍历时,需要保持出栈顺序为左---中---右,所以入栈必须是右---中---左
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root)
{
stack<TreeNode*>st;
vector<int>v1;
if(root!=nullptr)st.push(root);
while(!st.empty())
{
TreeNode*cur=st.top();
st.pop();
v1.push_back(cur->val);
if(cur->right)st.push(cur->right);
if(cur->left)st.push(cur->left);
}
return v1;
}
};
后序与前序在迭代遍历时改变一下入数据的顺序即可,实际上访问节点的顺序与入数据是同步的,但中序就不一样了,
中序遍历是左中右,先访问的是二叉树顶部的节点,然后一层一层向下访问,直到到达树左面的最底部,再开始处理节点(也就是在把节点的数值放进result数组中),这就造成了处理顺序和访问顺序是不一致的。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root)
{
stack<TreeNode*>st;
vector<int>v1;
TreeNode*cur=root;
while(cur!=nullptr||!st.empty())
{
if(cur!=nullptr)
{
st.push(cur);
cur=cur->left;
}
else
{
cur=st.top();
st.pop();
v1.push_back(cur->val);//处理数据
cur=cur->right;
}
}
return v1;
}
};
二,广度优先
2,层序遍历
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而是用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root)
{
vector<vector<int>>vv1;
queue<TreeNode*>q1;
if(root!=nullptr)q1.push(root);
while(!q1.empty())
{
vector<int>v1;
int size=q1.size();
for(int i=0;i<size;i++)
{
TreeNode*front=q1.front();
q1.pop();
v1.push_back(front->val);//处理数据的逻辑
if(front->left)q1.push(front->left);
if(front->right)q1.push(front->right);
}
vv1.push_back(v1);
}
return vv1;
}
};