树翻转二叉树

Posted pennyxia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树翻转二叉树相关的知识,希望对你有一定的参考价值。

题目链接:https://leetcode-cn.com/problems/invert-binary-tree/

技术图片

思路一:递归

将左右结点进行交换,递归的对左右节点的左右子树进行交换

  • 判断根结点是否为空或只有一个结点
  • 交换根结点的左右儿子
  • 对该结点的左右子树进行交换
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     TreeNode* invertTree(TreeNode* root) {
13         if(root==NULL||(root->left==NULL&&root->right==NULL))
14             return root;
15         //交换root的左右儿子
16         TreeNode* tmp=(TreeNode*)malloc(sizeof(TreeNode));
17         tmp=root->left;
18         root->left=root->right;
19         root->right=tmp;
20         //递归
21         invertTree(root->left);
22         invertTree(root->right);
23         return root;
24     }
25 };

 

思路二:DFS(栈存储)

循环交换每个结点的左右儿子,将未翻转的结点压入栈中,将所有栈中的结点交换完

  • 判断根结点是否为空或只有一个结点
  • 将根结点存入栈
  • 当栈不空时执行while循环,将栈顶元素的左右儿子交换,判断左右儿子是否为叶结点,如果不是叶结点则继续压栈
 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10
11 class Solution {
12 public:
13     TreeNode* invertTree(TreeNode* root) {
14        if(root==NULL||(root->left==NULL&&root->right==NULL))
15            return root;
16        stack<TreeNode*>s;
17        s.push(root);
18        while(!s.empty()){
19            //定义当前结点
20            TreeNode* node=s.top();
21            s.pop();
22            //交换当前结点的左右儿子
23            TreeNode* tmp=node->left;
24            node->left=node->right;
25            node->right=tmp;
26            //如果当前结点的儿子不空则入栈
27            if(node->left!=NULL)
28                 s.push(node->left);
29             if(node->right!=NULL)
30                 s.push(node->right);
31        }
32        return root;
33     }
34 };

 技术图片

 

 

思路三:BFS(队列存储)

循环交换每个结点的左右儿子,将未翻转的结点入队,将所有队列中的结点交换完

  • 判断根结点是否为空或只有一个结点
  • 将根结点存入队
  • 当队列不空时执行while循环,将队首的左右儿子交换,判断左右儿子是否为叶结点,如果不是叶结点则继续入队

与栈存储区别不大,对于队列push在队尾插入,pop在队首删除。

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10  #include <stack>
11 class Solution {
12 public:
13     TreeNode* invertTree(TreeNode* root) {
14        if(root==NULL||(root->left==NULL&&root->right==NULL))
15            return root;
16        queue<TreeNode*>q;
17        q.push(root);
18        while(!q.empty()){
19            //定义当前结点
20            TreeNode* node=q.front();
21            q.pop();
22            //交换当前结点的左右儿子
23            TreeNode* tmp=node->left;
24            node->left=node->right;
25            node->right=tmp;
26            //如果当前结点的儿子不空则入队
27            if(node->left!=NULL)
28                 q.push(node->left);
29             if(node->right!=NULL)
30                 q.push(node->right);
31        }
32        return root;
33     }
34 };

 

一个问题:采用不同的数据结构,使用递归和队列的执行用时是0ms,使用栈的执行用时是4ms。。。。差距好大啊,为啥(;′⌒`)

 

以上是关于树翻转二叉树的主要内容,如果未能解决你的问题,请参考以下文章

「经典题目回顾」翻转二叉树!

算法:二叉树翻转

难倒Homebrew发明人的翻转二叉树到底有多简单?

leecode刷题(24)-- 翻转二叉树

LeetCode951-翻转等价二叉树

226. 翻转二叉树简单树递归