struct TreeNode
{
int val;
struct TreeNode* left;
struct TreeNode* right;
};
有一个二叉树的根节点root,请创建一个数组arr接收二叉树的所有结点数据。
思路:首先我们需要知道数组的大小,那么就需要对二叉树计算其规模;然后进行遍历。
通过BTreeSize对二叉树的结点个数进行计算,然后创建PreOreder/InOrder/PostOrder函数进行前/中/后序遍历。
结点个数计算过程:
int BTreeSize(struct TreeNode* root)
{
return root == NULL ? 0 : 1 + BTreeSize(root->left) + BTreeSize(root->right);
}
使用递归计算结点个数。
前序遍历
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) {
int n = BTreeSize(root);
int* a = (int*)malloc(sizeof(int)*n);
*returnSize = n;
int i = 0;
PreOrder(root , a , &i);
return a;
}
中序遍历
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) {
int n = BTreeSize(root);
int* arr = (int*)malloc(sizeof(int)*n);
*returnSize = n;
int i = 0;
InOrder(root , arr , &i);
return arr;
}
后序遍历
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) {
int n = BTreeSize(root);
int* arr = (int*)malloc(sizeof(int)*n);
*returnSize = n;
int i = 0;
PostOrder(root , arr , &i);
return arr;
}
三种遍历写入数组其实都差不多,与三种顺序打印二叉树数据类似,唯一的可能出现的问题在于,遍历函数中的下标的形参要使用指针的形式,否则对于下标的变化可能存在问题。因为形参只是实参的一份临时拷贝,如果传值,每个栈区都会开辟下标的一个变量,可能导致变量的改变不同步。
虽然也可以在静态区开辟全局变量的空间,但是由于后续学习到多线程,可能会对全局变量进行了重复利用,因此最好还是参数传址。