【leetcode】94.二叉树的中序遍历
【leetcode】94.二叉树的中序遍历
/转载请说明出处与作者/
/作者:多巴胺dopamine/
1 问题描述
1.1 题目描述
给定一个二叉树的根节点root,返回它的中序遍历。
题目链接:94. 二叉树的中序遍历 - 力扣(LeetCode)
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
1.2 题目说明
本题是二叉树的中序遍历,相应的还有前序遍历和后序遍历。
这三种遍历均属于深度优先遍历,这三种遍历对应的代码,仅是部分代码顺序不一样,代码近似。
中序遍历:左,中,右(如果当前节点有左结点,那么就去遍历它的左结点,左结点全部遍历完后,再读取当前节点的值,之后再去遍历当前节点的右节点)
前序遍历:中,左,右
后序遍历:左,右,后
2 解决方法
2.1 解法一:递归
2.1.1 递归简述
一个函数执行的时候调用它自己。
2.1.2 递归使用条件
(1)问题能够分化为相似的子问题,解决子问题更加简单。
(2)有一个临界条件,不能够无限制的调用下去。必须有一个结束的条件,否则就是函数一直调用自己,永远没有停止。
2.1.3 代码(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().
*/
// 以下为解题代码
void medium_order_traversal();
# define size_number 100
/*
* 初始化函数。初始化一些参数的值。
* 参数说明:
* root,树的根节点; returnSize,返回数组的大小,它是一个指针,获取它所指向地址的值,使用(*retrunSize)。
*/
int* inorderTraversal(struct TreeNode* root, int* returnSize){
*returnSize=0;
// 开辟返回数组的空间
/// sizeof的使用参考:https://www.runoob.com/cplusplus/cpp-sizeof-operator.html
/// malloc的使用参考:https://www.runoob.com/cprogramming/c-function-malloc.html
int* return_array=(int *)malloc(sizeof(int)*size_number);
// 调用中序遍历函数
medium_order_traversal(root,returnSize,return_array);
// 返回数组
return return_array;
}
/*
* 中序遍历函数,递归
* 参数说明:
* root,树的根节点; returnSize,返回数组的大小; return_array,返回数组的指针。
*/
void medium_order_traversal(struct TreeNode* root,int* returnSize,int* return_array){
// 临界条件:root==NULL,只有在root不为NULL的时候才会执行下面的函数。
if(root){
// 遍历当前节点的左节点,递归
medium_order_traversal(root->left,returnSize,return_array);
// 当前节点的左结点遍历结束后,读取当前节点的值
return_array[*returnSize]=root->val;
(*returnSize)++;
// 遍历当前节点的右节点,递归。
medium_order_traversal(root->right,returnSize,return_array);
}
}
2.2 解法二:迭代(循环的意思)
2.2.1 迭代和递归的转换
递归实际上是系统为你维护了一个工作栈。(不了解栈的,可以先去了解一下)
而使用迭代,就是自己将这个工作栈模拟出来,并进行维护。
2.2.2 代码(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().
*/
// 以下为解题代码
void medium_order_traversal();
// 栈顶指针,栈底指针默认为0
int top;
/*
* 初始化函数。初始化一些参数的值。
* 参数说明:
* root,树的根节点; returnSize,返回数组的大小,它是一个指针,获取它所指向地址的值,使用(*retrunSize)。
*/
int* inorderTraversal(struct TreeNode* root, int* returnSize){
//栈的初始化
top=0;
//开辟栈空间,实际就是一个struct TreeNode指针的数组
/// sizeof的使用参考:https://www.runoob.com/cplusplus/cpp-sizeof-operator.html
/// malloc的使用参考:https://www.runoob.com/cprogramming/c-function-malloc.html
struct TreeNode** stack=(struct TreeNode**)malloc(sizeof(struct TreeNode*)*100);
*returnSize=0;
//开辟返回数组空间
int* return_array=(int*)malloc(sizeof(int)*100);
//调用中序遍历函数
medium_order_traversal(root,returnSize,return_array,stack);
//返回数组
return return_array;
}
/*
* 中序遍历函数,迭代
* 参数说明:
* root,树的根节点; returnSize,返回数组的大小; return_array,返回数组的指针;stack,栈的指针
*/
void medium_order_traversal(struct TreeNode* root, int* returnSize,int* return_array,struct TreeNode** stack){
//结束条件:栈为空且当前节点为NULL(即当前节点是叶子节点)(见解释一)
while(top!=0||root!=NULL){
//如果当前节点不为NULL,说明不是叶子结点,有值,执行下面代码。
while(root!=NULL){
//将当前节点入栈
stack[top]=root;
top++;
//指针指向当前节点的左结点,然后再判断是不是叶子结点
root=root->left;
}
//说明当前指针指向了叶子节点,没有值。将栈顶的节点出栈,读取其值
top--;
return_array[*returnSize]=(stack[top])->val;
(*returnSize)++;
//将当前指针换到刚刚读取节点的右节点
root=(stack[top])->right;
}
}
2.2.3 解释一
循环结束条件的确定(帮助理解,可以自己再画几个二叉树,来理解这个条件的确定)
例:
中序遍历结果应该为:D,B,E,A,C,F。
指针最后指向F的右节点,此时栈为空,该节点是叶子节点。
其他任何时候,均不满足此条件。