科软机试日常 - 翻转二叉树

目录

  • 前言
  • 一、题目
  • 二、具体代码
    • 1.1 层序遍历(BFS)
    • 1.2 先序遍历(DFS)、后序遍历
      • 1.2.1 递归算法
      • 1.2.2 非递归算法
  • 三、总结


前言

本人第一次写博客,请多多包容~


一、题目

leetcode:226.翻转二叉树
简要描述:给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
难度等级:easy
使用语言:C
思路:层序遍历、前中后序遍历

科软机试日常 - 翻转二叉树_第1张图片

二、具体代码

1.1 层序遍历(BFS)

struct TreeNode* invertTree(struct TreeNode* root) {
    struct TreeNode* p;
    struct TreeNode* queue[100]; //指针数组模拟队列
    int front = 0, rear = 0;     // front指针指向队头,rear指向队尾下一个元素
    if (root)
        queue[rear++] = root;    //根节点不为空则入栈
    while (front != rear) {      //队列不为空
        int size = rear - front; //当前层次中节点数目
        while (size--) {         //遍历该层次中所有节点
            p = queue[front++];  //将遍历到的节点出队
            struct TreeNode* tmp = p->left;
            p->left = p->right;
            p->right = tmp;      //交换左右子树,并将交换后的左右子树入队
            if (p->left)
                queue[rear++] = p->left;
            if (p->right)
                queue[rear++] = p->right;
        }
    }
    return root;
}

性能分析:

  • 时间复杂度:O(n),需要遍历到所有的节点
  • 空间复杂度:O(n),BFS需要使用到一个队列

1.2 先序遍历(DFS)、后序遍历

1.2.1 递归算法

递归三部曲:返回值(struct TreeNode*),终止条件(t为空),处理方式(根左右)

//先序遍历的顺序是:根左右;后序遍历只要将根的三行代码放到dfs后面就可以了
struct TreeNode* dfs(struct TreeNode* t){
    if(t==NULL)
        return t;
    //根:交换根节点左右子树
    struct TreeNode* p = t->left;
    t->left = t->right;
    t->right = p;
    dfs(t->left);   //左
    dfs(t->right);  //右
    return t;
}

struct TreeNode* invertTree(struct TreeNode* root) {
    return dfs(root);
}

性能分析:

  • 时间复杂度:O(n),需要遍历到所有的节点
  • 空间复杂度:O(n),递归工作栈深度为n

1.2.2 非递归算法

//先序遍历处理逻辑根左右。由于栈先进后出的性质,处理逻辑变为根右左
//后序遍历只要将交换左右子树的代码放到while循环最后就好了
struct TreeNode* invertTree(struct TreeNode* root) {
    struct TreeNode *stack[100], *p, *q; //用数组模拟栈
    int top = 0;
    if (root)
        stack[top++] = root;
    
    while (top) {
        //根:交换左右子树
        p = stack[--top];
        q = p->left;
        p->left = p->right;
        p->right = q;
        if (p->right)  //右
            stack[top++] = p->right;
        if (p->left) //左:如果左子树存在则入栈
            stack[top++] = p->left;

    }
    return root;
}

三、总结

本算法题是针对二叉树的遍历的应用,递归方式难度不大,非递归方式比较容易遗忘,建议每次做二叉树的遍历都用非递归的方式

你可能感兴趣的:(科软机试日常,深度优先,算法,c语言,广度优先)