题目描述
给定一个二叉树,返回它的中序 遍历。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
解题思路
树的遍历有两种方法,一种是递归,一种是循环,递归的方法比较简单,而循环必然要用到堆栈,对于先序遍历和中序遍历,在处理根节点时,由于要先后访问左右子树,因此访问左子树时,要暂时将根节点压入堆栈,不然后丢失右子树的信息,而入栈时访问节点数据,就是先序遍历,出栈时访问就是中序,理解了中序,再去做后序遍历就不难了,只不过后序遍历要两次入栈(要增加标志进行识别)。另外,在代码实现中,不用完全实现一个功能齐备的堆栈,可以简单的利用数组来实现,只不过数组的元素是节点指针。
代码
int TreeSize(struct TreeNode* root) //获取树的大小,以便动态申请内存
{
if(!root){
return 0;
} else {
return TreeSize(root->left)+TreeSize(root->right)+1;
}
}
void RInorderTraversal(struct TreeNode* root, int* returnSize,int *arr) //中序遍历递归实现
{
if (root){
RInorderTraversal(root->left, returnSize,arr);
arr[*returnSize] = root->val;
(*returnSize)++; //此处注意要加括号
// **parr = root->val;
// (*parr)++; //若此处采用指针,由于函数值传递,并不能修改上一级调用的指针的值,若改为**,则初始地址将被改变,需要记录开始的位置
RInorderTraversal(root->right, returnSize,arr);
}
}
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int treesize = TreeSize(root);
int* arr;
int len=0;
arr = (int*)malloc(sizeof(int)*treesize);
RInorderTraversal(root,&len,arr);
*returnSize = len;
return arr;
}
//中序遍历非递归实现
/*
int* inorderTraversal(struct TreeNode* root, int* returnSize){
int treesize = TreeSize(root);
//printf("%d",treesize);
int* arr;
struct TreeNode** TreeStack;
int len=0;
arr = (int*)malloc(sizeof(int)*treesize);
TreeStack = (struct TreeNode**)malloc(sizeof(struct TreeNode*)*treesize);
int index = -1;
while(root || index!=-1){
while(root){
TreeStack[++index] = root; //入栈,index 为当前栈顶指针,为-1时,空
root = root->left;
}
root = TreeStack[index--];
arr[len++] = root->val;
root = root->right;
}
*returnSize = len;
return arr;
}
*/
总结
- *arr++ 与 (*arr)++ 的区别,前者为指针++后取值,后者为对指针指向的元素++。
- 注意函数调用时值的传递,若要将被调用函数内的修改传回调用者,要用地址传递,对于多级指针,易忽略该问题,尤其注意递归场景,可以使用全局变量代替。
- 巧妙使用数组来做堆栈。