二叉树的前序遍历

  • 题目
  • 函数原型
  • 算法设计:递归
  • 算法设计:迭代
  • 算法设计:Morris 前序遍历



 


题目

给你二叉树的根节点 root ,返回它节点值的 前序 遍历。

递归算法很简单,你可以通过迭代算法完成吗?
 


函数原型

C 的函数原型:

/**
 * 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* preorderTraversal(struct TreeNode* root, int* returnSize){

}

 


算法设计:递归

思路:根据定义,二叉树的每个都是二叉树,所以可以通过调用一个函数重复遍历所有结点… …前序遍历:按照访问根节点、左子树、右子树的方式遍历这棵树。

void recurion(struct TreeNode* root, int* arr, int* size) {
    if (root == NULL) 
        return;
    arr[(*size)++] = root->val;
    recurion(root->left, arr, size);
    recurion(root->right, arr, size);
}

int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    int* res = malloc(sizeof(int) * 1024);
    *returnSize = 0;
    recurion(root, res, returnSize);
    return res;
}
  • 时间复杂度:[144].二叉树的前序遍历_二叉树
  • 空间复杂度:[144].二叉树的前序遍历_二叉树
     

算法设计:迭代

思路:把递归的过程模拟出来。

int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    int* res = malloc(sizeof(int) * 1024);
    *returnSize = 0;
    if (root == NULL) {
        return res;
    }

    struct TreeNode* stk[1024];
    struct TreeNode* node = root;
    int stk_top = 0;
    while (stk_top > 0 || node != NULL) {
        while (node != NULL) {
            res[(*returnSize)++] = node->val;
            stk[stk_top++] = node;
            node = node->left;
        }
        node = stk[--stk_top];
        node = node->right;
    }
    return res;
}
  • 时间复杂度:[144].二叉树的前序遍历_二叉树
  • 空间复杂度:[144].二叉树的前序遍历_二叉树
     

算法设计:Morris 前序遍历

  • 思路:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    int* res = malloc(sizeof(int) * 2000);
    *returnSize = 0;
    if (root == NULL) {
        return res;
    }

    struct TreeNode *p1 = root, *p2 = NULL;

    while (p1 != NULL) {
        p2 = p1->left;
        if (p2 != NULL) {
            while (p2->right != NULL && p2->right != p1) {
                p2 = p2->right;
            }
            if (p2->right == NULL) {
                res[(*returnSize)++] = p1->val;
                p2->right = p1;
                p1 = p1->left;
                continue;
            } else {
                p2->right = NULL;
            }
        } else {
            res[(*returnSize)++] = p1->val;
        }
        p1 = p1->right;
    }
    return res;
}
  • 时间复杂度:[144].二叉树的前序遍历_二叉树
  • 空间复杂度:[144].二叉树的前序遍历_算法设计_06