目录
1. 二叉树的前序遍历
1.1 题目链接与描述
题目链接:
题目描述:
给你二叉树的根节点 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 题目链接与描述
题目链接:
题目描述:
给定一个二叉树的根节点 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 题目链接与描述
题目链接:
题目描述:
给你一棵二叉树的根节点 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;
}