二叉树学习小结01

前言

前天在CSDN上看到了一个著名的学习金字塔图,如下:
在这里插入图片描述
这让我想起,我国著名教育学家孔子曾说过: “学而时习之,不亦说乎?”
所以本着认真负责的态度,打算把这几天学习的二叉树知识消化一下,强化自己对二叉树的理解。

正文

1、二叉平衡搜索树与红黑树的区别

在写第一篇二叉树学习的博客的时,我根据自学二叉树的相关知识,写下了二叉树学习的一些个人心得。
其实红黑树就是一种二叉平衡搜索树,这两个树不是独立的,所以C++中 map、multimap、set、multiset的底层实现机制是二叉平衡搜索树 ,再具体一点是 红黑树。

2、为什么要给二叉树节点定义构造函数

二叉树的节点函数定义如下:

struct TreeNode {
    int val;//值
    TreeNode *left;//左子树
    TreeNode *right;//右子树
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

定义了如下的构造函数
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
它也可以不写,但是new一个新的节点的时候就比较麻烦。

例如有构造函数,定义初始值为1的节点:

TreeNode* a = new TreeNode(1);

没有构造函数的话就要这么写:

TreeNode* a = new TreeNode(); 
a->val = 1; 
a->left = NULL;
a->right = NULL;  

所以,你也能理解为什么需要构造函数了。

3、有没有更牛的二叉树遍历方法

在学习二叉树的遍历的时候,我写下了递归法、还有迭代法
还有一种牛逼的遍历方式: morris遍历。

morris遍历是二叉树遍历算法的超强进阶算法,morris遍历可以将非递归遍历中的空间复杂度降为O(1)。我其实也没有研究过,以后学习完之后再来补这个坑。

4、递归与迭代哪个方法好

毋庸置疑,从时间复杂度上其实迭代法和递归法差不多(在不考虑函数调用开销和函数调用产生的堆栈开销),但是 空间复杂度上,递归开销会大一些,因为递归需要系统堆栈存参数返回值等等。
不管怎么说,面试的时候,二叉树的遍历题, 至少递归和迭代都要会写。

5、翻转二叉树的中序遍历递归问题

在写翻转二叉树学习笔记时,提到中序遍历不能用递归写法, 否则某些节点的左右孩子会翻转两次。
如果非要使用递归的中序的方式写,也可以,如下:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if (root == NULL) return root;
        invertTree(root->left);         // 左
        swap(root->left, root->right);  // 中
        invertTree(root->left);         // 注意 这里依然要遍历左孩子,因为中间节点已经翻转了
        return root;
    }
};

代码虽然可以,但这毕竟不是真正的递归中序遍历了。

但使用迭代方式统一写法的中序是可以的。

如下:

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        stack<TreeNode*> st;
        if (root != NULL) st.push(root);
        while (!st.empty()) {
            TreeNode* node = st.top();
            if (node != NULL) {
                st.pop();
                if (node->right) st.push(node->right);  // 右
                st.push(node);                          // 中
                st.push(NULL);
                if (node->left) st.push(node->left);    // 左

            } else {
                st.pop();
                node = st.top();
                st.pop();
                swap(node->left, node->right);          // 节点处理逻辑
            }
        }
        return root;
    }
};

为什么这个中序就是可以的呢, 因为这是用栈来遍历,而不是靠指针来遍历,避免了递归法中翻转了两次的情况。

每日寄语

总结完后,感觉跟着大佬学习,自己又强大了不少,芜湖~
希望自己有朝一日也能变强。

在这里插入图片描述

参考文献

二叉树小结

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓梦林

都看到这里了,支持一下作者呗~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值