递归实现二叉树的前、中、后序遍历

什么是二叉树?

二叉树是一种特殊的树形数据结构,它的每个节点最多只能有两个子节点,通常被称为左子节点和右子节点。这个定义非常直观,形象地描述了二叉树的形状。然而,这只是二叉树的表面特征。

首先,二叉树的每个节点都有一个数据元素。这个元素可以是任何类型的数据,如数字、字符甚至是其他的数据结构。这些数据元素存储在节点的左子节点和右子节点中,这使得二叉树成为一个非常灵活的数据存储方式。

其次,二叉树的性质决定了它的应用范围非常广泛。比如,我们可以利用二叉树进行高效的搜索和排序。由于每个节点最多只有两个子节点,因此我们可以很容易地遍历整个树,找到我们需要的元素。此外,二叉搜索树和AVL等高级数据结构也都是在二叉树的基础上构建的。

然而,尽管二叉树有许多优点,但也尤其局限性。例如,当节点的子节点数量过多时,二叉树的搜索效率会降低。这就需要我们在实际应用中,根据具体的需求和场景,选择最合适的数据结构。

总的来说,二叉树是一种简单而强大的数据结构,它为我们提供了一种有效的组织和处理数据的方式。通过深入学习和理解二叉树,可以更好地理解数据结构的原理,进一步提高我们的编程技能。

二叉树的定义

在C++中,可以使用结构体的方式定义一个二叉树(来自LeetCode):

C++ 复制代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

在JavaScript中,可以使用函数来定义一个二叉树(来自LeetCode):

JavaScript 复制代码
/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */

二叉树的前、中、后序遍历指的是访问根节点的顺序。比如前序遍历是优先访问根节点,再遍历左子树,最后遍历右子树;中序遍历则是优先遍历左子树,再访问根节点,最后遍历右子树;同理,后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点。

二叉树的前序遍历

前序遍历的顺序是:根节点->左子树->右子树。

递归实现的方式是,如果二叉树非空,则先访问根节点,然后递归地前序遍历左子树和右子树。

C++ 复制代码
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        preorder(root, result);

        return result;
    }

    void preorder(TreeNode* root, vector<int> &result) {
        if (!root) return;

        result.push_back(root->val);
        preorder(root->left, result);
        preorder(root->right, result);
    }
};
JavaScript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var preorderTraversal = function(root) {
    const result = [];

    const preOrder = function(root) {
        if (!root) return;

        result.push(root.val);
        preOrder(root.left);
        preOrder(root.right);
    }

    preOrder(root);

    return result;
};

二叉树的中序遍历

中序遍历的顺序是:左子树->根节点->右子树。

递归实现的方式是,如果二叉树非空,则先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

C++ 复制代码
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> result;
        inorder(root, result);

        return result;
    }

    void inorder(TreeNode* root, vector<int> &result) {
        if (!root) return;

        inorder(root->left, result);
        result.push_back(root->val);
        inorder(root->right, result);
    }
};
JavaScript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var inorderTraversal = function(root) {
    const result = [];

    const inOrder = function(root) {
        if (!root) return;

        inOrder(root.left);
        result.push(root.val);
        inOrder(root.right);
    }

    inOrder(root);

    return result;
};

二叉树的后序遍历

后序遍历地的顺序是:左子树->右子树->根节点。

递归实现的方式是,如果二叉树非空,则先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。

C++ 复制代码
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> result;
        postorder(root, result);
        
        return result;
    }

    void postorder(TreeNode* root, vector<int> &result) {
        if (!root) return;

        postorder(root->left, result);
        postorder(root->right, result);
        result.push_back(root->val);
    }
};
JavaScript 复制代码
/**
 * @param {TreeNode} root
 * @return {number[]}
 */
var postorderTraversal = function(root) {
    const result = [];

    const postOrder = function(root) {
        if (!root) return;

        postOrder(root.left);
        postOrder(root.right);

        result.push(root.val);
    }

    postOrder(root);

    return result;
};

一维数组转二叉树

一维数组和二叉树是两种常见的数据结构,各有其独特的特性和用途。然而,有时我们需要在这两种数据结构之间进行转换。

首先,我们来理解这两种数据结构的基本概念。一维数组是一种线性的数据结构,可以通过索引快速访问任意元素;而二叉树则是一种层次结构的数据结构,每个节点最多有两个子节点,通常称为左子节点和右子节点。

假设我们有一个一维数组,其中包含n个元素,可以按照以下步骤将其转换为二叉树:

  1. 创建一个空的二叉树;
  2. 从一维数组的第一个元素开始,将其作为根节点放入二叉树中;
  3. 对于一维数组中的下一个元素,如果其值小于根节点的值,则将其作为左子节点放入左子树中;否则,将其作为右子节点放入右子树中;
  4. 重复步骤3,直到处理完一维数组中的所有元素。
JavaScript 复制代码
function TreeNode(val, left, right) {
     this.val = (val === undefined) ? 0 : val;
     this.left = (left === undefined) ? null : left;
     this.right = (right === undefined) ? null : right;
}

function buildBinaryTree(arr) {
    var root = null;
    if (!arr || arr.length === 0) return root;
    root = new TreeNode(arr[0]);
    for (var i = 1; i < arr.length; i++) {
        insertNode(arr[i], root);
    }
    
    return root;
}

function insertNode(current, root) {
    if (root === null) root = { val: current, left: null, right: null };
    else if (current <= root.val) root.left = insertNode(current, root.left);
    else root.right = insertNode(current, root.right);
    
    return root;
}
相关推荐
依然鸣13 小时前
蓝桥杯多校模拟赛(第二场)题解
数据结构·c++·经验分享·学习·算法·图论
依然鸣13 小时前
蓝桥杯多校模拟赛 题解
数据结构·c++·经验分享·学习·算法·蓝桥杯
AKA__Zas14 小时前
芝士算法(位运算)
java·开发语言·算法·leetcode·学习方法
wabs66614 小时前
关于图论【Kruskal算法|卡码网53.寻宝的思考】
数据结构·算法·图论·卡码网
hans汉斯14 小时前
人工智能与机器人研究|面向无标签数据的三维场景语义理解方法研究
人工智能·神经网络·算法·信息可视化·cnn·机器人
小程故事多_801 天前
从A2C、TRPO、PPO到GRPO,强化学习策略梯度算法完整演进与大模型落地实战解析
人工智能·算法
2601_956121971 天前
二分算法(知识点+题目)
c++·算法
AndrewHZ1 天前
【LLM技术全景】阶段总结:技术原理篇核心知识回顾
人工智能·深度学习·算法·语言模型·大模型·llm·芯片开发
小星星闪亮登场1 天前
2026萌新联赛第三场-- (郑州轻工业大学)
数据结构·c++·经验分享·算法·贪心算法·排序算法·深度优先
冻柠檬飞冰走茶1 天前
PTA基础编程题目集 7-8超速判断(C++语言实现)
开发语言·数据结构·c++·算法