前序遍历
递归写法
二叉树的三种递归写法十分相似,我们简单来分析一下递归逻辑。
递归终止条件:
每次调用时先检查是否满足递归终止条件,当前节点为NULL,递归结束。
问题的解决方法:
- 在前序遍历中,先处理当前节点,然后递归地处理左子树和右子树。
- 在中序遍历中,先递归地处理左子树,然后处理当前节点,最后递归地处理右子树。
- 在后序遍历中,先递归地处理左子树,然后递归地处理右子树,最后处理当前节点。
递归的等价关系,缩小规模的方法:
处理完当前节点,对左孩子,右孩子进行递归处理。
void preorder(int* ret, struct TreeNode* root, int* returnSize) {
if (root == NULL) {
return;
}
ret[(*returnSize)++] = root->val;
preorder(ret, root->left, returnSize);
preorder(ret, root->right, returnSize);
}
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = 0;
int* ret = (int*)malloc(sizeof(int) * 101);
preorder(ret, root, returnSize);
return ret;
}
迭代写法
迭代写法其实是在模拟递归的过程,使用栈来实现。
前序遍历顺序:中左右
入栈顺序:中 右左
出栈顺序:中 左右
我们先把根节点入栈出栈,然后先入栈右孩子,在入栈左孩子,这样子就能实现左孩子先出栈,右孩子后出栈。
注意我们对某一节点左右孩子操作前先将该节点出栈,这样就实现了中左右的顺序。
下面来看看代码
int* preorderTraversal(struct TreeNode* root, int* returnSize) {
*returnSize = 0;
if (root == NULL) {
return NULL;
}
// 返回结果数组
int* ret = (int*)malloc(sizeof(int) * 101);
// 声明一个大小为101的数组模拟栈
struct TreeNode* stack[101];
// 初始化栈顶指针为0
int anstop = 0;
// 将根节点压入栈中
stack[anstop++] = root;
// 遍历二叉树
while (anstop) {
struct TreeNode* cur