Skip to content

翻转二叉树 ​

LeetCode 226

问题描述 ​

给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。

示例 1:

输入:root = [4,2,7,1,3,6,9]
输出:[4,7,2,9,6,3,1]

示例 2:

输入:root = [2,1,3]
输出:[2,3,1]

示例 3:

输入:root = []
输出:[]

提示:

  • 树中节点数目范围在 [0, 100] 内
  • -100 <= Node.val <= 100

思路 ​

递归 ​

  1. 如果根节点为空,直接返回 nullptr。
  2. 交换根节点的左右子节点。
  3. 递归地对左子树和右子树进行翻转。

非递归 ​

  1. 使用一个栈来存储待翻转的节点。
  2. 遍历栈中的节点,对于每个节点,交换其左右子节点,并将其左右子节点入栈。
  3. 直到栈为空为止。

图解 ​

  1. 申请一个栈,将根节点放入栈中。

  1. 如果栈不为空,获取栈顶节点,弹出栈顶节点。

  1. 交换当前节点的左右节点,并将当前节点的左右节点入栈。

  1. 此时栈不为空,弹出栈顶节点。

  1. 交换当前节点的左右节点,并将当前节点的左右节点入栈。

  1. 栈不为空,弹出栈顶节点。

当前节点无子节点,不交换,也无需入栈。

  1. 栈不为空,弹出栈顶元素。

当前节点无子节点,不交换,也无需入栈。

  1. 栈不为空,弹出栈顶节点。

  1. 交换当前节点的左右节点,并将当前节点的左右节点入栈。

  1. 栈不为空,弹出栈顶节点。

当前节点无子节点,不交换,也无需入栈。

  1. 栈不为空,弹出栈顶节点。

当前节点无子节点,不交换,也无需入栈。

此时,栈为空,退出循环,并返回4。

参考代码 ​

C++ ​

递归 ​
cpp
#include <iostream>
#include <queue>
using namespace std;

// 二叉树节点的定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 递归函数:翻转二叉树
TreeNode* invertTree(TreeNode* root) {
    if (root == nullptr) {
        return nullptr; // 如果根节点为空,直接返回 nullptr
    }

    // 交换根节点的左右子节点
    TreeNode* temp = root->left;
    root->left = root->right;
    root->right = temp;

    // 递归地对左右子树进行翻转
    invertTree(root->left);
    invertTree(root->right);

    return root; // 返回翻转后的根节点
}

// 创建二叉树
TreeNode* createTree(vector<int>& nodes, int index) {
    if (index >= nodes.size() || nodes[index] == -1) {
        return nullptr; // 如果节点为空,则返回nullptr
    }
    TreeNode* root = new TreeNode(nodes[index]); // 创建当前节点
    root->left = createTree(nodes, 2 * index + 1); // 创建左子树
    root->right = createTree(nodes, 2 * index + 2); // 创建右子树
    return root; // 返回当前节点
}

// 销毁二叉树
void destroyTree(TreeNode* root) {
    if (!root) return; // 如果根节点为空,直接返回
    destroyTree(root->left); // 递归销毁左子树
    destroyTree(root->right); // 递归销毁右子树
    delete root; // 删除当前节点
}

// 中序遍历二叉树(测试用)
void inorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    inorderTraversal(root->left);
    cout << root->val << " ";
    inorderTraversal(root->right);
}

int main() {
    vector<int> nodes = {4, 2, 7, 1, 3, 6, 9}; // 定义二叉树的先序遍历序列
    TreeNode* root = createTree(nodes, 0); // 创建二叉树

    cout << "翻转前的二叉树(中序遍历):" << endl;
    inorderTraversal(root); // 输出翻转前的二叉树(中序遍历)
    cout << endl;

    root = invertTree(root); // 翻转二叉树

    cout << "翻转后的二叉树(中序遍历):" << endl;
    inorderTraversal(root); // 输出翻转后的二叉树(中序遍历)
    cout << endl;

    destroyTree(root); // 销毁二叉树

    return 0;
}
非递归 ​
cpp
#include <iostream>
#include <stack>
using namespace std;

// 二叉树节点的定义
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 非递归函数:翻转二叉树
TreeNode* invertTree(TreeNode* root) {
    if (root == nullptr) {
        return nullptr; // 如果根节点为空,直接返回 nullptr
    }

    stack<TreeNode*> stk; // 辅助栈,用于存储待翻转的节点
    stk.push(root); // 将根节点入栈

    while (!stk.empty()) {
        TreeNode* node = stk.top(); // 获取栈顶节点
        stk.pop(); // 弹出栈顶节点

        // 交换当前节点的左右子节点
        TreeNode* temp = node->left;
        node->left = node->right;
        node->right = temp;

        // 将当前节点的左右子节点入栈
        if (node->left) {
            stk.push(node->left);
        }
        if (node->right) {
            stk.push(node->right);
        }
    }

    return root; // 返回翻转后的根节点
}

// 创建二叉树
TreeNode* createTree(vector<int>& nodes, int index) {
    if (index >= nodes.size() || nodes[index] == -1) {
        return nullptr; // 如果节点为空,则返回nullptr
    }
    TreeNode* root = new TreeNode(nodes[index]); // 创建当前节点
    root->left = createTree(nodes, 2 * index + 1); // 创建左子树
    root->right = createTree(nodes, 2 * index + 2); // 创建右子树
    return root; // 返回当前节点
}

// 销毁二叉树
void destroyTree(TreeNode* root) {
    if (!root) return; // 如果根节点为空,直接返回
    destroyTree(root->left); // 递归销毁左子树
    destroyTree(root->right); // 递归销毁右子树
    delete root; // 删除当前节点
}

// 中序遍历二叉树(测试用)
void inorderTraversal(TreeNode* root) {
    if (root == nullptr) return;
    inorderTraversal(root->left);
    cout << root->val << " ";
    inorderTraversal(root->right);
}

int main() {
    vector<int> nodes = {4, 2, 7, 1, 3, 6, 9}; // 定义二叉树的先序遍历序列
    TreeNode* root = createTree(nodes, 0); // 创建二叉树

    cout << "翻转前的二叉树(中序遍历):" << endl;
    inorderTraversal(root); // 输出翻转前的二叉树(中序遍历)
    cout << endl;

    root = invertTree(root); // 翻转二叉树

    cout << "翻转后的二叉树(中序遍历):" << endl;
    inorderTraversal(root); // 输出翻转后的二叉树(中序遍历)
    cout << endl;

    destroyTree(root); // 销毁二叉树

    return 0;
}

Java ​

java
import java.util.*;

// 二叉树节点的定义
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

// 翻转二叉树的函数
public class Solution {
    public TreeNode invertTree(TreeNode root) {
        if (root == null) {
            return null; // 如果根节点为空,直接返回 null
        }

        Stack<TreeNode> stack = new Stack<>(); // 辅助栈,用于存储待翻转的节点
        stack.push(root); // 将根节点入栈

        while (!stack.isEmpty()) {
            TreeNode node = stack.pop(); // 弹出栈顶节点

            // 交换当前节点的左右子节点
            TreeNode temp = node.left;
            node.left = node.right;
            node.right = temp;

            // 将当前节点的左右子节点入栈
            if (node.left != null) {
                stack.push(node.left);
            }
            if (node.right != null) {
                stack.push(node.right);
            }
        }

        return root; // 返回翻转后的根节点
    }

    // 创建二叉树的函数
    public TreeNode createTree(Integer[] nodes, int index) {
        if (index >= nodes.length || nodes[index] == null) {
            return null; // 如果节点为空,则返回 null
        }
        TreeNode root = new TreeNode(nodes[index]); // 创建当前节点
        root.left = createTree(nodes, 2 * index + 1); // 创建左子树
        root.right = createTree(nodes, 2 * index + 2); // 创建右子树
        return root; // 返回当前节点
    }

    // 销毁二叉树的函数
    public void destroyTree(TreeNode root) {
        if (root == null) return; // 如果根节点为空,直接返回
        destroyTree(root.left); // 递归销毁左子树
        destroyTree(root.right); // 递归销毁右子树
    }

    // 中序遍历二叉树(测试用)
    public void inorderTraversal(TreeNode root) {
        if (root == null) return;
        inorderTraversal(root.left);
        System.out.print(root.val + " ");
        inorderTraversal(root.right);
    }

    public static void main(String[] args) {
        Integer[] nodes = {4, 2, 7, 1, 3, 6, 9}; // 定义二叉树的先序遍历序列
        Solution solution = new Solution();
        TreeNode root = solution.createTree(nodes, 0); // 创建二叉树

        System.out.println("翻转前的二叉树(中序遍历):");
        solution.inorderTraversal(root); // 输出翻转前的二叉树(中序遍历)
        System.out.println();

        root = solution.invertTree(root); // 翻转二叉树

        System.out.println("翻转后的二叉树(中序遍历):");
        solution.inorderTraversal(root); // 输出翻转后的二叉树(中序遍历)
        System.out.println();

        solution.destroyTree(root); // 销毁二叉树
    }
}

Python ​

python
# 二叉树节点的定义
class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

# 翻转二叉树的函数
def invertTree(root: TreeNode) -> TreeNode:
    if not root:
        return None  # 如果根节点为空,直接返回 None

    stack = [root]  # 辅助栈,用于存储待翻转的节点

    while stack:
        node = stack.pop()  # 弹出栈顶节点

        # 交换当前节点的左右子节点
        node.left, node.right = node.right, node.left

        # 将当前节点的左右子节点入栈
        if node.left:
            stack.append(node.left)
        if node.right:
            stack.append(node.right)

    return root  # 返回翻转后的根节点

# 创建二叉树的函数
def createTree(nodes, index):
    if index >= len(nodes) or nodes[index] is None:
        return None  # 如果节点为空,则返回 None
    root = TreeNode(nodes[index])  # 创建当前节点
    root.left = createTree(nodes, 2 * index + 1)  # 创建左子树
    root.right = createTree(nodes, 2 * index + 2)  # 创建右子树
    return root  # 返回当前节点

# 销毁二叉树的函数
def destroyTree(root):
    if not root:
        return  # 如果根节点为空,直接返回
    destroyTree(root.left)  # 递归销毁左子树
    destroyTree(root.right)  # 递归销毁右子树

# 中序遍历二叉树(测试用)
def inorderTraversal(root):
    if not root:
        return
    inorderTraversal(root.left)
    print(root.val, end=" ")
    inorderTraversal(root.right)

# 测试用例
nodes = [4, 2, 7, 1, 3, 6, 9]  # 定义二叉树的先序遍历序列
root = createTree(nodes, 0)  # 创建二叉树

print("翻转前的二叉树(中序遍历):")
inorderTraversal(root)  # 输出翻转前的二叉树(中序遍历)
print()

root = invertTree(root)  # 翻转二叉树

print("翻转后的二叉树(中序遍历):")
inorderTraversal(root)  # 输出翻转后的二叉树(中序遍历)
print()

destroyTree(root)  # 销毁二叉树