二叉树的前序/中序/后序遍历—采用递归与迭代两种方法实现嗷

简介: 二叉树的前序/中序/后序遍历—采用递归与迭代两种方法实现嗷

二叉树的前序/中序/后序遍历—采用递归与迭代两种方法实现(以leetcode二叉树遍历为例题)


前序遍历


递归算法


/**
 * 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().
 */
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int * returns = (int *)malloc(sizeof(int)* 110);
    preorder(root,returns,returnSize);
    return returns;
}
void preorder(struct TreeNode* root,int returns[],int *returnSize)
{
    if(root == NULL)
    {   
        return;
    }
    // printf("%d",root->val);
    // preorder(root,returns,&returnSize);
    returns[*returnSize] = root->val;
    (*returnSize)++;
    preorder(root->left,returns,returnSize);
    preorder(root->right,returns,returnSize);
}


迭代


这里比较详细🔎(复杂)的写出来,包括栈的存储方式定义,入栈,出栈,判空以及初始化方法,下面中序与后序遍历时进行了优化!减少了多个方法函数!

::重点记忆后边的写法::

/**
 * 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().
 */
typedef struct stack{
    struct TreeNode* data[110];
    int top;
}stack;
void push(stack *s,struct TreeNode *x)
{
    s->data[(s->top)] = x;
    (s->top)++;
}
struct TreeNode *pop(stack *s,struct TreeNode *x)
{
    x = s->data[--(s->top)];
    // printf("%d",x->val);
    return x;
}
void init(stack *s)
{
    (s->top) = 0;
}
int empty(stack s)
{
    if(s.top == 0)
        return 0;
    return 1;
}
void visit(struct TreeNode* x,int returns[],int *returnSize)
{
    returns[(*returnSize)++] = x->val;
}
int* preorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int* returns = (int *)malloc(sizeof(int)* 110);
    struct TreeNode *m;
    m = root;
    stack s;
    init(&s);
    while(m != NULL || empty(s)!= 0)
    {
        if(m)
        {
            visit(m,returns,returnSize);
            push(&s,m);
            // printf("s%ds",m->val);
            m = m->left;
        }
        else
        {
            m = pop(&s,m);
            m = m->right;
        }
    }
    return returns;
}


中序遍历


递归算法


/**
 * 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().
 */
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int *returns = (int *)malloc(sizeof(int )* 110);
    inorder(root,returns,returnSize);
    return returns;
}
void inorder(struct TreeNode* root,int returns[],int *returnSize)
{
    if(root == NULL)
        return;
    inorder(root->left,returns,returnSize);
    returns[(*returnSize)++] = root->val;
    inorder(root->right,returns,returnSize);
}


迭代


我们也可以用迭代的方式实现递归函数,两种方式是等价的,区别在于递归的时候隐式地维护了一个栈,而我们在迭代的时候需要显式地将这个栈模拟出来,其余的实现与细节都相同,代码附下。

/**
 * 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().
 */
int* inorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int* returns = (int *)malloc(sizeof(int )*110);
    struct TreeNode *s[110];
    int top = 0;
    struct TreeNode *m = root;
    while(m!=NULL || top != 0)
    {
        if(m)
        {
            s[top++] = m;
            m = m->left;
        }
        else
        {
            m = s[--top];
            returns[(*returnSize)++] = m->val;
            m = m -> right;
        }
    }
    return returns;
}


后序遍历


递归


/**
 * 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().
 */
int* postorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int *returns = (int *)malloc(sizeof(int)* 110);
    postorder(root,returns,returnSize);
    return returns;
}
void postorder(struct TreeNode* root,int returns[],int *returnSize)
{
    if(root == NULL)
    {
        return;
    }
    postorder(root->left,returns,returnSize);
    postorder(root->right,returns,returnSize);
    returns[(*returnSize)++] = root->val;
}


迭代 (卡了一会儿)


/**
 * 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().
 */
int* postorderTraversal(struct TreeNode* root, int* returnSize){
    *returnSize = 0;
    int *returns = (int *)malloc(sizeof(int)* 110);
    struct TreeNode* data[110];
    int top = 0;
    struct TreeNode* m = root;
    struct TreeNode* pre = NULL;
    while(m || top != 0)
    {
        while(m)
        {
            pre = m;
            data[top++] = m;
            m = m->left;
        }
        m = data[--top]; //当前m为空,肯定要m找到上一个结点,才能判断
        if(m->right != NULL && m->right != pre) //下面还有子结点
        {
            data[top++] = m;
            m = m->right;
        }
        else
        {
            pre = m;  //pre记录现在的结点 当m->right与pre相等时可以记录当前结点
            returns[(*returnSize)++] = pre->val;
            m = NULL; //m去栈里找栈顶元素
        }   
    }
    return returns;
}
相关文章
|
5月前
排序二叉树的创建及先序、中序、后序输出二叉树
排序二叉树的创建及先序、中序、后序输出二叉树
27 1
|
6月前
二叉树的几个递归问题
二叉树的几个递归问题
25 0
|
1月前
搜索二叉树(二叉搜索树)的实现(递归与非递归)
搜索二叉树(二叉搜索树)的实现(递归与非递归)
|
4月前
|
存储 C++
二叉搜索树详解以及C++实现二叉搜索树(递归和非递归)
二叉搜索树详解以及C++实现二叉搜索树(递归和非递归)
47 0
|
6月前
递归与非递归实现二叉树的前中后序遍历!!
递归与非递归实现二叉树的前中后序遍历!!
23 0
|
11月前
|
存储
非递归方式实现二叉树的前、中、后序遍历
非递归方式实现二叉树的前、中、后序遍历
Day14——二叉树的前中后序遍历(迭代&&递归)
Day14——二叉树的前中后序遍历(迭代&&递归)
78 0
|
数据采集 算法
数据结构与算法—二叉树的层序、前序中序后序(递归、非递归)遍历
层序遍历。听名字也知道是按层遍历。我们知道一个节点有左右节点。而每一层一层的遍历都和左右节点有着很大的关系。也就是我们选用的数据结构不能一股脑的往一个方向钻,而左右应该均衡考虑。这样我们就选用队列来实现。
160 0
数据结构与算法—二叉树的层序、前序中序后序(递归、非递归)遍历
|
算法 Java BI
【算法】二叉树遍历算法总结:前序中序后序遍历
二叉树遍历是非常经典的算法题,也是二叉树的一道基础算法题。 但是在平常的笔试面试中,其出现的频率其实并不是特别的高,我推测是这种题目相对来说比较基础,算是一个基础知识点。 比如剑指offer中出现的后序遍历题目,是给出一个数字序列,让你判断是不是平衡二叉树后序遍历序列,这样出题的难度比直接让你写后序遍历难很多。 但是,二叉树遍历容易吗?在递归方法下,前中后序遍历都是一个思路,理解起来也比较容易。 但是只是用迭代的话,二叉树遍历其实是有难度的!,这也是为什么LeetCode会在这三题题目的下方写出进阶: 递归算法很简单,你可以通过迭代算法完成吗?这句话了。
326 0