前言
三种遍历方式对应着LeetCode的三道题目,分别是:
前序遍历:144. Binary Tree Preorder Traversal
中序遍历:94. Binary Tree Inorder Traversal
后序遍历:145. Binary Tree Postorder Traversal
先说一下,递归方式很简单,所以目前本文暂且都是递归方式,迭代方式还没添上,后续更新
三种遍历方式把,长得贼像,其实就是一个先添加哪个节点的问题
举例的二叉树
总的来说把,除了空二叉树,这个树把树的每个节点的所有情况都包括了,拿来举例比较好
前序遍历:A → B → D → E → G → C → F
中序遍历:D → B → G → E → A → C → F
后序遍历:D → G → E → B → F → C → A
树的数据结构
这是自定义的一个TreeNode,很简单的结构,左节点、右节点、本身的值
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
递归方式
前序遍历
先遍历根节点,然后遍历它的左子树,再遍历它的右子树
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
res.add(root.val);
res.addAll(preorderTraversal(root.left));
res.addAll(preorderTraversal(root.right));
return res;
}
}
中序遍历
对于一个节点来说,先遍历左子树,再遍历本身,最后遍历右子树
也就是要把一个树,拆成左子树、根节点、右子树这三部分
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
res.addAll(inorderTraversal(root.left));
res.add(root.val);
res.addAll(inorderTraversal(root.right));
return res;
}
}
后序遍历
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
res.addAll(postorderTraversal(root.left));
res.addAll(postorderTraversal(root.right));
res.add(root.val);
return res;
}
}
迭代方式
前序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
void preorder(struct TreeNode *root, int *res, int *resSize) {
if (!root) return;
res[*resSize] = root->val;
(*resSize)++;
preorder(root->left, res, resSize);
preorder(root->right, res, resSize);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
int *res = malloc(sizeof(int) * 2000);
*returnSize = 0;
preorder(root, res, returnSize);
return res;
}
中序遍历
void inorder(struct TreeNode* root, int* res, int* resSize) {
if (!root) return;
inorder(root->left, res, resSize);
res[(*resSize)++] = root->val;
inorder(root->right, res, resSize);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int* res = malloc(sizeof(int) * 100);
*returnSize = 0;
inorder(root, res, returnSize);
return res;
}
后序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* postorderTraversal(struct TreeNode* root, int* returnSize){
int *res = malloc(sizeof(int) * 100);
*returnSize = 0;
if (!root) return res;
struct TreeNode **stk = malloc(sizeof(struct TreeNode *) * 100);
int top = 0;
struct TreeNode *prev = NULL;
while (root != NULL || top > 0) {
while (root != NULL) {
stk[top++] = root;
root = root->left;
}
root = stk[--top];
if (root->right == NULL || root->right == prev) {
res[(*returnSize)++] = root->val;
prev = root;
root = NULL;
} else {
stk[top++] = root;
root = root->right;
}
}
return res;
}