/** * File: tree_node.hpp * Created Time: 2021-12-19 * Author: krahets (krahets@163.com) */ #pragma once #include #include using namespace std; /* 二叉树节点结构体 */ struct TreeNode { int val{}; // 节点的值 val {} 表示初始化为 0 或 nullptr ({} 是 C++11 的新特性: 值初始化) int height = 0; // 节点的高度 TreeNode *parent{}; // 父节点 {} 表示初始化为 nullptr TreeNode *left{}; // 左孩子 {} 表示初始化为 nullptr TreeNode *right{}; // 右孩子 {} 表示初始化为 nullptr TreeNode() = default; // 默认构造函数 explicit TreeNode(int x, TreeNode *parent = nullptr) : val(x), parent(parent) { } // 构造函数: 初始化节点的值为x, 父节点为parent }; // 序列化编码规则请参考: // https://www.hello-algo.com/chapter_tree/array_representation_of_tree/ // 二叉树的数组表示: // [1, 2, 3, 4, None, 6, 7, 8, 9, None, None, 12, None, None, 15] // 二叉树的链表表示: // /——— 15 // /——— 7 // /——— 3 // | \——— 6 // | \——— 12 // ——— 1 // \——— 2 // | /——— 9 // \——— 4 // \——— 8 /* 将列表反序列化为二叉树:递归 */ /* vectorToTreeDFS 是一个递归函数,用于将一个整数类型的向量 arr 转换为一棵二叉树,并返回树的根节点。 函数的参数包括 arr 和 i。arr 是一个存储整数值的向量,i 是当前节点在向量中的索引。 函数首先检查当前索引 i 是否越界或者对应的值是否为 INT_MAX。如果是的话,表示当前节点为空节点,函数返回 nullptr。 如果当前节点不为空,函数会创建一个新的 TreeNode 对象,并将 arr[i] 的值赋给节点的 val 成员变量。 然后,函数会递归调用 vectorToTreeDFS 函数来构建当前节点的左子树和右子树。左子树的索引为 2 * i + 1,右子树的索引为 2 * i + 2。递归调用的目的是将 arr 中的元素逐个转换为树的节点,并建立节点之间的父子关系。 最后,函数返回根节点,完成整个向量到二叉树的转换过程。 这个函数使用深度优先搜索(DFS)的方式来构建二叉树。通过递归调用自身,可以依次处理每个节点,并构建出完整的二叉树结构。 */ TreeNode *vectorToTreeDFS(vector &arr, int i) { if (i < 0 || i >= arr.size() || arr[i] == INT_MAX) { return nullptr; } TreeNode *root = new TreeNode(arr[i]); root->left = vectorToTreeDFS(arr, 2 * i + 1); // 递归构建左子树 root->right = vectorToTreeDFS(arr, 2 * i + 2); // 递归构建右子树 return root; // 返回根节点 } /* 将列表反序列化为二叉树 */ TreeNode *vectorToTree(vector arr) { return vectorToTreeDFS(arr, 0); } /* 将二叉树序列化为列表:递归 */ /* treeToVecorDFS 是一个递归函数,用于将二叉树的节点值按照深度优先搜索(DFS)的顺序存储到一个向量中。 函数的参数包括: root:指向当前节点的指针,表示当前递归的节点。 i:表示当前节点在向量中的索引位置。 res:存储节点值的向量的引用。 函数的实现逻辑如下: 首先,检查当前节点是否为空。如果为空,表示已经遍历到叶子节点或空节点,直接返回。 然后,通过一个循环,将向量 res 扩展到足够的长度,以便能够存储当前节点的值。循环条件是 i 大于等于向量 res 的大小。 在向量 res 中,将索引为 i 的位置的值更新为当前节点的值。 递归调用 treeToVecorDFS 函数,分别处理当前节点的左子节点和右子节点。对于左子节点,索引位置为 2 * i + 1;对于右子节点,索引位置为 2 * i + 2。 这个函数的作用是将二叉树的节点值按照深度优先搜索的顺序存储到一个向量中,可以用于后续的数据处理或分析。 */ void treeToVecorDFS(TreeNode *root, int i, vector &res) { if (root == nullptr) return; while (i >= res.size()) { res.push_back(INT_MAX); // 初始化为 INT_MAX } res[i] = root->val; treeToVecorDFS(root->left, 2 * i + 1, res); treeToVecorDFS(root->right, 2 * i + 2, res); } /* 将二叉树序列化为列表 */ vector treeToVecor(TreeNode *root) { vector res; treeToVecorDFS(root, 0, res); return res; } /* 释放二叉树内存 */ void freeMemoryTree(TreeNode *root) { if (root == nullptr) return; // 先要依次递归释放左右子树的内存,再释放根节点的内存 freeMemoryTree(root->left); freeMemoryTree(root->right); delete root; }