题目:给定一个二叉树的根节点 root ,返回它的 前序遍历、中序遍历、后序遍历、广度优先遍历和深度优先遍历
一 前序遍历
二 中序遍历
2.1 定义
给一个二叉树的节点,先遍历二叉树的左子树,然后遍历根节点,然后访问二叉树的右子树
2.2 递归解法
1.递归遍历,隐形的维护了一个栈
递归遍历算法比较简单,因为二叉树本身的建立也是通过递归进行建立的。所以二叉树的子树也是二叉树,根据这个思想,遍历算法如下:
1)访问二叉树的左子树
2)访问根节点
3)访问二叉树的右子树
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
//解法一 递归解法
int *print_mid_result(struct TreeNode* root, int* returnSize, int* ret) {
if (root == NULL) {
return ret;
}
print_mid_result(root -> left, returnSize, ret);
ret[(*returnSize)] = root -> val;
(*returnSize)++;
print_mid_result(root -> right, returnSize, ret);
return ret;
}
通过这种递归的函数调用关系,实际上在访问二叉树的节点的时候,函数需要一直找到可以输出的哪个节点,所以就需要一直往下寻找,同时上面的就一直保持着,相当于是将前面不满足输出的节点进行了压栈,然后等到输出的条件满足以后,再进行弹栈输出,所以非递归算法就是根据这个思想,把栈直接实现出来,然后模拟递归调用的步骤进行访问。
2.3 非递归解法
思想:维护一个栈,当访问一个节点的时候,如果这个节点不满足输出条件,就压入栈中,如果满足输出条件,就弹出栈并输出。
代码如下:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
// 解法二 迭代解法 使用栈进行处理,将递归的隐形栈变成显性的
// 弹出栈的条件是 判断是否满足是最左边的节点,如果是就弹出,不是就压栈
int *print_mid_result_step(struct TreeNode* root, int* returnSize, int* ret)
{
struct TreeNode* stk = (struct TreeNode*)malloc(sizeof(struct TreeNode) * 101);
int top = -1;
while ((top > (-1)) || (root != NULL)) {
while (root != NULL) { // 寻找最左边的节点
top++;
stk[top] = *root;
root = root -> left;
}
root = &(stk[top]); // 栈顶元素满足弹栈条件,弹出
top--;
ret[(*returnSize)] = root -> val;
(*returnSize)++;
root = root -> right;
}
free(stk);
stk = NULL;
return ret;
}