今日内容:
- 理论基础
- 递归遍历
- 迭代遍历
- 统一迭代
一、二叉树的理论基础
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
注意二叉树的定义。
二、二叉树的递归遍历
递归三要素:
-
确定递归函数的参数和返回值: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
-
确定终止条件: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
-
确定单层递归的逻辑: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
几个题目链接:144.二叉树的前序遍历 (opens new window)
94.二叉树的中序遍历 (opens new window)
145.二叉树的后序遍历 (opens new window)
此处三者比较雷同,会一个就能会三个,此处列出前序遍历。
/**
* 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:
void transit(TreeNode* cur ,vector<int>& vec){
if(cur==NULL){
return;
}
vec.push_back(cur->val);
transit(cur->left,vec);
transit(cur->right,vec);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
transit(root,result);
return result;
}
};
三、二叉树迭代遍历
思路,迭代遍历需要用到栈,其中前中后序的遍历的代码还有一定的区别。
前序:
/**
* 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> 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) st.push(node->right);
if(node->left) st.push(node->left);
}
return result;
}
};
中序代码和前序有不同,因为处理顺序和访问顺序不一致。
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> st;
vector<int> result;
if(root!=NULL) st.push(root);
while(!st.empty()){
TreeNode* node =st.top();
if(node!=NULL){
st.pop();
if(node->right) st.push(node->right);
st.push(node);
st.push(NULL);
if(node->left) st.push(node->left);
}else{
st.pop();
node=st.top();
st.pop();
result.push_back(node->val);
}
}
return result;
}
};
前序和后序均为中序代码稍微变动两行(在入栈顺序处)
结语:很多种写法以前没接触过,应该好好熟悉一下。