【数据结构】_二叉树OJ第二弹(返回数组的遍历专题)

发布于:2025-06-25 ⋅ 阅读:(20) ⋅ 点赞:(0)

目录

1. 二叉树的前序遍历

1.1 题目链接与描述

1.2 解题思路

1.3 程序

2. 二叉树中序遍历

2.1 题目链接与描述

2.2 解题思路

2.3 程序

3. 二叉树后序遍历

3.1 题目链接与描述

3.2 解题思路

3.3 程序


1. 二叉树的前序遍历

1.1 题目链接与描述

题目链接:

144. 二叉树的前序遍历 - 力扣(LeetCode)

题目描述:

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

1.2 解题思路

注意该题目与直接打印前序遍历结果的不同,该题目要求遍历结果存储到一个数组中进行打印:

遍历函数的大致实现思路与之前直接打印遍历结果的实现基本一致,只是需要将打印的语句修改为存入数组的语句。

同时需要为返回的数组开辟空间,为了实现空间的高效合理应用,需要考虑开辟大小问题;

为了实现正确的存储,需要设计下标指明下一个存储位置。

1.3 程序

/**
 * 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 TreeSize(struct TreeNode* root) {
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
// 前序遍历二叉树并按序存入数组
void PreOrder(struct TreeNode* root, int* a, int* pi) {
    if (root == NULL)
        return;
    a[(*pi)++] = root->val;
    PreOrder(root->left, a, pi);
    PreOrder(root->right, a, pi);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
    // returnSize为输出型参数
    *returnSize = TreeSize(root);
    int* a = (int*)malloc(sizeof(int) * (*returnSize));
    int i=0;
    PreOrder(root, a, &i);
    return a;
}

注意点:

1. 关于动态空间开辟的方式:

(1)可以采用之前顺序表的扩容方式,先malloc 4字节,随后再动态扩容;

(2)题目说明“树中节点数目在范围 [0, 100] 内”,可一次性扩容100字节,但可能造成浪费;

(3)遍历给定的二叉树,计算结点个数来确定要开辟的空间大小:

// 遍历二叉树确定动态开辟空间大小
int TreeSize(struct TreeNode* root) {
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}

2. 关于输出型参数:

要求实现的函数preorderTraversal中,除用于接收当前二叉树根结点指针变量struct TreeNode* root外,还有一个int*类型的参数 returnSize。

力扣oj对于返回值为数组的题目要求:除返回数组外,还需要返回数组的大小,故而给定一个输出型参数。为了保证调用函数能实现对数组尺寸的修改,将输出型参数定义为指针类型,通过在函数中解引用进行操作。

3. 关于数组下标i作为参数:

该题目中要求将前序遍历结果按序存到数组中,故而前序遍历函数中还需要一个数组下标参数i:

// 前序遍历二叉树并按序存入数组
void PreOrder(struct TreeNode* root, int* a, int i) {
    if (root == NULL)
        return;
    a[i++] = root->val;
    PreOrder(root->left, a, i);
    PreOrder(root->right, a, i);
}


上述写法是错误的,递归调用PreOrder时会出现元素覆盖问题,比如:

在3作为根结点的二叉树遍历中将i递增为1,递归调用其左子树,在1作为根结点的子树遍历中,将i递增为2,遍历完毕后返回到以3为根结点的二叉树的遍历函数中,再递归调用其右子树,此时就会出现本应将元素2存放至下标为2的位置上,但由于下标采用传值调用,使得将元素2存放至下标为1的位置处,导致元素覆盖,最终返回值为:[3,2,随机值]。

为了解决该问题,需要将数组下标参数设计为传址调用方式:

// 前序遍历二叉树并按序存入数组
void PreOrder(struct TreeNode* root, int* a, int* pi) {
    if (root == NULL)
        return;
    a[(*pi)++] = root->val;
    PreOrder(root->left, a, pi);
    PreOrder(root->right, a, pi);
}

2. 二叉树中序遍历

2.1 题目链接与描述

题目链接:

94. 二叉树的中序遍历 - 力扣(LeetCode)

题目描述:

给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。

2.2 解题思路

与上题一致,仅需修改遍历函数的递归与将元素存入数组的顺序。

2.3 程序

/**
 * 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 TreeSize(struct TreeNode* root) {
    return root == NULL ? 0 : TreeSize(root->left) + TreeSize(root->right) + 1;
}
void InOrder(struct TreeNode* root, int* a, int* pi) {
    if (root == NULL)
        return;
    InOrder(root->left, a, pi);
    a[(*pi)++] = root->val;
    InOrder(root->right, a, pi);
}
int* inorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize = TreeSize(root);
    int* a = (int*)malloc(sizeof(int) * (*returnSize));
    int i = 0;
    InOrder(root, a, &i);
    return a;
}

3. 二叉树后序遍历

3.1 题目链接与描述

题目链接:

145. 二叉树的后序遍历 - 力扣(LeetCode)

题目描述:

给你一棵二叉树的根节点 root ,返回其节点值的 后序遍历 

3.2 解题思路

与上题一致,仅需修改遍历函数的递归与将元素存入数组的顺序。

3.3 程序

/**
 * 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 TreeSize(struct TreeNode* root){
    return root==NULL?0:TreeSize(root->left)+TreeSize(root->right)+1;
}
void PostOrder(struct TreeNode* root, int* a, int* pi){
    if(root==NULL)
    return;
    PostOrder(root->left, a, pi);
    PostOrder(root->right, a, pi);
    a[(*pi)++]=root->val;
}
int* postorderTraversal(struct TreeNode* root, int* returnSize) {
    *returnSize=TreeSize(root);
    int* a = (int*)malloc(sizeof(int)*(*returnSize));
    int i=0;
    PostOrder(root, a, &i);
    return a;
}


网站公告

今日签到

点亮在社区的每一天
去签到