递归:
class Solution {
public:
vector<int> ans;
vector<int> preorderTraversal(TreeNode* root) {
dfs(root);
return ans;
}
void dfs(TreeNode* root){
if(root==NULL) return;
ans.push_back(root->val);
dfs(root->left);
dfs(root->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> preorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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); // 右
if (node->left) st.push(node->left); // 左
st.push(node); // 中
st.push(NULL);
} else {
st.pop();
node = st.top();
st.pop();
result.push_back(node->val);
}
}
return result;
}
};
1、中序遍历包含递归和非递归两种做法
2、递归方法包含一个隐式栈,所以也可以用栈的方法实现遍历。
3、非递归方法每次沿左节点遍历,找到无左孩子的节点,输出再找右节点,以此类推。
递归:
class Solution {
public:
vector<int> ans;
vector<int> inorderTraversal(TreeNode* root) {
dfs(root);
return ans;
}
void dfs(TreeNode* root){
if(root==NULL) return;
dfs(root->left);
ans.push_back(root->val);
dfs(root->right);
}
};
非递归:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> res;
stack<TreeNode*> stk;
while (root != nullptr || !stk.empty()) {
while (root != nullptr) {
stk.push(root);
root = root->left;
}
root = stk.top();
stk.pop();
res.push_back(root->val);
root = root->right;
}
return res;
}
};
统一模板:
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
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;
}
};
递归:
class Solution {
public:
vector<int> ans;
vector<int> postorderTraversal(TreeNode* root) {
dfs(root);
return ans;
}
void dfs(TreeNode* root){
if(root==NULL) return;
dfs(root->left);
dfs(root->right);
ans.push_back(root->val);
}
};
非递归:
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();
st.pop();
result.push_back(node->val);
if (node->left) st.push(node->left);
// 相对于前序遍历,这更改一下入栈顺序 (空节点不入栈)
if (node->right) st.push(node->right); // 空节点不入栈
}
reverse(result.begin(), result.end()); // 将结果反转之后就是左右中的顺序了
return result;
}
};
统一模板:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> st;
if (root != NULL) st.push(root);
while (!st.empty()) {
TreeNode* node = st.top();
if (node != NULL) {
st.pop();
st.push(node); // 中
st.push(NULL);
if (node->right) st.push(node->right); // 右
if (node->left) st.push(node->left); // 左
} else {
st.pop();
node = st.top();
st.pop();
result.push_back(node->val);
}
}
return result;
}
};
1、层序遍历算法使用广度优先搜索,算法使用队列实现。
2、输出格式是按行分的二维数组,所以记录每次输出时队列的长度。
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
queue<TreeNode*> q;
if (root==NULL) return {
};
q.push(root);
vector<vector<int>> ans;
while(!q.empty()){
vector<int> set;
//队列的长度是个变量,必须事先记录
int num=q.size();
for(int i=0;i<num;i++) {
TreeNode* temp=q.front();
q.pop();
set.push_back(temp->val);
if(temp->left!=NULL) q.push(temp->left);
if(temp->right!=NULL) q.push(temp->right);
}
ans.push_back(set);
}
return ans;
}
};
1、思路与二叉树层序遍历类似,使用广搜,树用链表,用双端队列存树节点,返回二维数组
2、根据行的奇偶决定从双端队列的头插还是尾插
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
vector<vector<int>> ans;
if (!root)
return ans;
queue<TreeNode*> nodeQueue;
nodeQueue.push(root);
bool isOrderLeft = true;
while (!nodeQueue.empty()) {
deque<int> levelList;
int size = nodeQueue.size();
for (int i = 0; i < size; ++i) {
auto node = nodeQueue.front();
nodeQueue.pop();
if (isOrderLeft)
levelList.push_back(node->val);
else
levelList.push_front(node->val);
if (node->left)
nodeQueue.push(node->left);
if (node->right)
nodeQueue.push(node->right);
}
ans.emplace_back(vector<int>{
levelList.begin(), levelList.end()});
isOrderLeft = !isOrderLeft;
}
return ans;
}
递归函数传入最小值和最大值,递归遍历左右子树时,值不能超过最大最小值的范围
class Solution {
public:
bool helper(TreeNode* root, long long lower, long long upper) {
if (root == nullptr)
return true;
if (root -> val <= lower || root -> val >= upper)
return false;
return helper(root -> left, lower, root -> val) && helper(root -> right, root -> val, upper);
}
bool isValidBST(TreeNode* root) {
return helper(root, LONG_MIN, LONG_MAX);
}
};
1、平衡二叉树左右子树的高度差不超过1
2、使用双递归函数的方法进行判断,一个递归函数负责递归判断每个节点是不是平衡二叉树
3、第二个递归函数负责判断每个节点的深度是多少
class Solution {
public:
int height(TreeNode* root) {
if (root == NULL)
return 0;
else
return max(height(root->left), height(root->right)) + 1;
}
bool isBalanced(TreeNode* root) {
if (root == NULL)
return true;
else
return abs(height(root->left) - height(root->right)) <= 1
&& isBalanced(root->left) && isBalanced(root->right);
}
};
用层序遍历广度优先搜索队列做,当出现空节点时,如果后面没有节点,则是完全二叉树,有节点则不是
bool isCompleteTree(TreeNode* root) {
queue<TreeNode*> q;
q.push(root);
int flag=0;
while(!q.empty()){
TreeNode* temp=q.front();
q.pop();
if(temp==nullptr)
flag=1;
else{
if(flag==1)
return false;
else {
q.push(temp->left);
q.push(temp->right);
}
}
}
return true;
}
题目要求的双向链表是二叉搜索树的中序遍历,先遍历一遍把节点存在节点数组中,在两轮遍历把前后指针接上
class Solution {
public:
vector<Node*> list;
Node* treeToDoublyList(Node* root) {
//先中序遍历,用vector存储两边,再处理双向循环
if(root==NULL) return NULL;
dfs(root);
int n=list.size();
list[0]->left=list[n-1];
list[n-1]->right=list[0];
//遍历完的结果,必须left和right都找一遍
for(int i=0;i<n-1;i++)
list[i]->right=list[i+1];
for(int i=1;i<n;i++)
list[i]->left=list[i-1];
return list[0];
}
void dfs(Node* root){
if(root==NULL)
return;
dfs(root->left);
list.push_back(root);
dfs(root->right);
}
};