144.二叉树的前序遍历
递归法:
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
先写递归函数,再写遍历
class Solution {
public:
//先写遍历算法
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == NULL) return;
vec.push_back(cur -> val); //中
traversal(cur -> left, vec); //左
traversal(cur -> right, vec);//右
}
//前序遍历
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root, result);
return result;
}
};
迭代法:
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
vector<int> result;
if(root == NULL)return result;
st.push(root); //根节点放入栈内
while(!st.empty()){
TreeNode* node = st.top();
st.pop();
result.push_back(node->val);
if(node->right != NULL) st.push(node->right); //右先放入后出
if(node->left != NULL) st.push(node->left); //左后放入栈内先出
}
return result;
}
};
94.二叉树的中序遍历
递归法:
class Solution {
public:
//中序递归法:左中右
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == NULL)return;
traversal(cur->left, vec); //左
vec.push_back(cur->val); //中
traversal(cur->right,vec); //右
}
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root,result);
return result;
}
};
迭代法:
迭代法:
存放元素(将元素放入栈中)和处理元素(将元素放入result容器中)并不同时进行(交错进行)。先找到二叉树左面的最底部(此时cur->left == NULL),在这个过程中,将经过的每一个节点都放入栈内。
然后进行处理元素环节:栈内存放了左、中节点的元素,将其分别弹出后,如果存在有孩子,指针指向其右孩子并将右孩子放入栈内。再看右孩子有没有左孩子。以此循环。
学习到的处理方法:
当cur ==NULL是,此时栈首存放的是上一次cur指向的元素,因此cur = st.top();然后st.pop();
cur = st.top(); //如果cur指向空,那么就将cur指向上一个存入栈的元素
st.pop();
result.push_back(cur->val); //将该结点的元素放入result容器
cur = cur->right;
整体代码:
class Solution {
public:
//迭代法中序遍历
vector<int> inorderTraversal(TreeNode* root) {
TreeNode* cur = root;
stack<TreeNode*> st;
vector<int> result;
while(cur != NULL || !st.empty()){
//cur != NULL 当前结点不为空,就一直找其左子树
if(cur != NULL){
st.push(cur);
cur = cur->left; //指向当前节点的左孩子
}
else{
cur = st.top(); //如果cur指向空,那么就将cur指向上一个存入栈的元素
st.pop();
result.push_back(cur->val); //将该结点的元素放入result容器
cur = cur->right;
}
}
return result;
}
};
145.二叉树的后序遍历
递归法:
class Solution {
public:
//后序遍历:左右中
void traversal(TreeNode* cur, vector<int>& vec){
if(cur == NULL)return;
traversal(cur -> left, vec);
traversal(cur -> right, vec);
vec.push_back(cur -> val);
}
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
traversal(root, result);
return result;
}
};
迭代法:
指针的更新:TreeNode* node = st.top(); //此处包含了node指针的更新
class Solution {
public:
//迭代法后序遍历(前序:中左右 -> 中右左 ->左右中(后序))
vector<int> postorderTraversal(TreeNode* root) {
stack<TreeNode*>st;
vector<int> result;
if(root == NULL)return result;
st.push(root);
while(!st.empty()){
TreeNode* node = st.top(); //此处包含了node指针的更新
st.pop();
result.push_back(node->val);
if(node->left != NULL)st.push(node->left);//空节点不入栈
if(node->right != NULL)st.push(node->right);
}
reverse(result.begin(),result.end()); //翻转
return result;
}
};