Tree Problems 二叉树 5.2

119 阅读3分钟

刚刚学完搜索这章 所以一开始面对关于树的题目 最先想到的也是DFS和BFS。但发现树更多的做法是回溯。写下来做过的题和思路以便后续复习。

树一直以来都不算我很熟悉的专题,今天看了一下,确实我对于树没有进行过专项的学习和总结。

这篇文章对应算法竞赛:入门到进阶的5.2 二叉树 P66

树的基础

树的基础知识是很重要的 这样在后续写代码的途中代码出错率能降低很多。(即使你的思路不是最优解。

树是非线性数据结构,它能很好的描述数据的层次关系。树形结构的现实场景很常见。例如,文件目录,书本的目录就是典型的树形特征。 二叉树是最常用的树形结构,特别适合程序设计,常常将一般的树转换为二叉树来处理。本章讲解二叉树的定义/遍历问题,以及二叉搜索树。

5.2.1 二叉树的存储

1. 二叉树的性质

二叉树的每个结点最多有俩个子节点,分别是左孩子/右孩子,以及它们为根的子树成为左子树和右子树。

二叉树的第i层最多有2^(i-1)个节点。如果每一层的结点数都是满的,那么它为满二叉树。

2. 二叉树的存储结构

二叉树一般由指针来实现,并指向左右节点。

struct node{
   int val;
   node* l, r
}
删除树
void deleteTree(TreeNode* root){
   if(root == nullptr) return;
   deleteTree(root->left);
   deleteTree(root->right);
   delete root;
}

单纯delete root会引发memory Leak.

5.2.2 二叉树的遍历 Tree Traversal

宽度优先搜索

深度优先搜索

94. Binary Tree Inorder Traversal

另: 在二叉搜索树中,中序遍历实现了排序功能,返回结果是有序排列。如果已知某棵二叉树的3种遍历,可以把这棵树构造出来,即“中序遍历 + 后续遍历” 或者 “中序遍历 + 先续遍历”,都能确认这棵树。

但是,如果不知道中序遍历,只有“先序遍历 + 后续遍历”,不能确认一棵树。

LeetCode 相关例题

实战演练

image.png

回溯

image.png

这道是很好的回溯思考题。因为我没有能够很好的处理左右子树的nullptr问题,也就是说对于题目的思路不够清晰所以出错。

class Solution {
    TreeNode* prev = nullptr;
public:
    TreeNode* inorderSuccessor(TreeNode* root, TreeNode* p) {
        if(!root) return nullptr;

        //在左子树中寻找
        TreeNode* left = inorderSuccessor(root->left. p);
        if(left) return left;

        //如果前一个节点是目标节点,则当前节点为后继
        if(prev == p) return root;

        //更新当前节点
        prev = root;

        //在右子树中查找
        TreeNode* right = inorderSuccessor(root->right, p);
        if(right) return right;

        return nullptr;
    }
};

Time Complexity:O(n) Space Complexity: 最佳情况(平衡树): 空间复杂度 O(logn)最坏情况(非平衡树): 空间复杂度 O(log n)。

----To be continue