day_14
传送门
-
二叉树的递归遍历 - 题目链接/文章讲解/视频讲解
-
二叉树迭代遍历 - 题目链接/文章讲解/视频讲解
-
统一形式的二叉树迭代遍历 - 题目链接/文章讲解/视频讲解
递归遍历
- 前序
typedef struct TreeNode TreeNode;
void preOrder(TreeNode* root, int* ret, int* returnSize){
if (root == NULL){
return;
}
ret[(*returnSize)++] = root ->val;
preOrder(root->left, ret, returnSize);
preOrder(root->right, ret, returnSize);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int* ret = (int* )malloc(sizeof(int) * 100);
*returnSize = 0;
preOrder(root, ret, returnSize);
return ret;
}
- 中序
typedef struct TreeNode TreeNode;
void inorder(TreeNode* root, int* ret, int* returnSize){
if (root == NULL){
return;
}
if (root->left != NULL){
inorder(root->left, ret, returnSize);
}
ret[(*returnSize)++] = root -> val;
if (root->right != NULL){
inorder(root->right, ret, returnSize);
}
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int* ret = (int* )malloc(sizeof(int)* 100);
*returnSize = 0;
inorder(root, ret, returnSize);
return ret;
}
- 后序
typedef struct TreeNode TreeNode;
void postOrder(TreeNode* root, int* ret, int* returnSize){
if (root == NULL){
return;
}
// 左
if (root->left != NULL){
postOrder(root->left, ret, returnSize);
}
// 右
if (root->right != NULL){
postOrder(root->right, ret, returnSize);
}
// 根节点
ret[(*returnSize)++] = root -> val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize){
int* ret = (int* )malloc(sizeof(int)* 100);
*returnSize = 0;
postOrder(root, ret, returnSize);
return ret;
}
迭代遍历
- 前序
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> ansList = new ArrayList<>();
if (root == null){
return ansList;
}
// 初始化栈
stack.push(root);
TreeNode cur = null;
// 开始遍历,当栈不为空的时候,就一直遍历下去
while (!stack.isEmpty()){
cur = stack.pop();
if (cur == null) continue;
else {
// 当前节点不为空的时候,先将该节点的数据放入 list 中,再将右左子节点入栈
ansList.add(cur.val);
if (cur.right != null) stack.push(cur.right);
if (cur.left != null) stack.push(cur.left);
}
}
return ansList;
}
}
- 中序
- 思路
Push 非空的左子节点 Pop 左子节点null时,pop父节点,右子节点为空的时候,pop父节点的父亲 如何pop父亲的父亲呢?判断完左为 null, 先pop父亲,再转入右子节点,pop 父亲的父亲
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> ansList = new ArrayList<>();
if (root == null){
return ansList;
}
// 记录当前遍历到的节点
TreeNode cur = root;
while (!stack.isEmpty() || cur != null){
if (cur != null){
stack.push(cur);
cur = cur.left;
}
// 左子树为空时,pop 父节点
// 右子树为空时,左子树已被pop(即跟节点被pop了,pop根节点的根节点),
else {
cur = stack.pop();
ansList.add(cur.val);
cur = cur.right;
}
}
return ansList;
}
}
- 后序
- 思路
- 前序 ==> 中左右
- 中左右 ===>(入栈顺序修改) 中右左 ===>(反转操作) 左中右
- 思路
public class PostOrder {
public List<Integer> postorderTraversal(TreeNode root) {
Stack<TreeNode> stack = new Stack<>();
List<Integer> ansList = new ArrayList<>();
if (root == null){
return ansList;
}
// 初始化栈
stack.push(root);
TreeNode cur = null;
// 开始遍历,当栈不为空的时候,就一直遍历下去
while (!stack.isEmpty()){
cur = stack.pop();
if (cur == null) continue;
else {
// 当前节点不为空的时候,先将该节点的数据放入 list 中,再将左右子节点入栈
ansList.add(cur.val);
if (cur.left != null) stack.push(cur.left);
if (cur.right != null) stack.push(cur.right);
}
}
Collections.reverse(ansList);
return ansList;
}
}