图文示例二叉树的编码实现过程_球二叉树编码(1),2024年最新客户端开发面试题目

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注网络安全)
img

正文

if(root == null){
    return;
}
//1、首先遍历当前root结点的左子树
inOrderTraversal(root.left);

//2、遍历当前结点root中的数据,并进行输出
System.out.printf("%s ",root.data);

//3、遍历当前结点root的右子树
inOrderTraversal(root.right);

}


中序遍历的代码编程如上,先遍历当前结点root的左子树,接着将当前结点root中元素输出,最后遍历当前结点root的右子树。调用上述inOrderTraversal函数,将A结点作为参数传入。可以得到中序二叉树中序遍历的结果为:B D A G E C H F I。


#### 2.3 后序遍历



public void postOrderTraversal(Node root){
if(root == null){
return;
}
//1、先遍历当前结点的左子树
postOrderTraversal(root.left);
//2、先遍历当前结点的右子树
postOrderTraversal(root.right);
//3、最后当前结点的数据data
System.out.printf("%s ",root.data);
}


如上所示的后序遍历操作,在调用`postOrderTraversal`函数时,将树的根结点A作为参数传入。可以得到后序遍历的序列为:D B G E H I F C A。


#### 2.4 层序遍历(广度遍历)


前面三种遍历方式前序、中序、后序均属于深度遍历,前文我们曾经提到,层序遍历又称广度遍历。主要是按层对树进行结点的遍历。在编程实现上,层序遍历与深度遍历的操作稍有不同,具体实现如下:



public void levelOrderTraversal(Node root){
if(root == null){
return;
}

Queue<Node> queue = new LinkedList<Node>();
//首先访问第1层的根节点
queue.add(root);

while(!queue.isEmpty()){
    //从队列中取出一个结点,并输出该结点,意味着已经访问过该结点
    Node node = queue.poll();
    System.out.printf("%s ", node.data);

    //判断并将该结点的左子树存入到队列中
    if(node.left != null){
        queue.add(node.left);
    }

    //判断并将该结点的右子树存入到队列中
    if(node.right != null){
        queue.add(node.right);
    }
}

}


如上述代码所示,在进行层序遍历(广度遍历)时,我们借用了前面已经学习过的数据结构队列Queue,将每次访问的结点输出后,同时将结点的左右子树存入到队列中。因为我们知道队列的特点是,元素输入的顺序与输出的顺序会保持一致,因此在每次取数据时,总是先取出之前存入的数据;同时,又会把下一层数据(左右子树)存入队列中。最终,上述代码对树的层序遍历结果是:A B C D E F G H I。


## 二. 二叉查找树


### 1. 二叉查找树概念


**二叉查找树,全称为Binary Search Tree,简称BST**。从名字中我们容易理解,二叉查找树是在二叉树的基础上,同时具备了某些特性的一种特殊的二叉树型结构。二叉查找树相较于二叉树,额外满足以下几个条件:


(1). 若左子树不为空,则左子树上的所有结点的值均小于根结点位置上的值;


(2). 若右子树不为空,则右子树上的所有结点的值均大于根结点位置上的值;


(3). 左、右子树也都是二叉查找树。


总结上述几个条件的,我们可以用一居话概括二叉查找树的特点,**左子树的数值小于根结点点数值,根结点数值小于右子树结点数值,整个二叉树结点的数值从左至右是有序的**。


基于以上所总结的二叉查找树的特点,有的资料和教材也把查找树称之为二叉搜索树,以及二叉排序树(Binary Sort Tree,简称BST)。因此,大家要记住以下结论特征:**左子树结点数值 < 根结点数值 < 右子树结点数值**。


![](https://img-blog.csdnimg.cn/img_convert/f068a4af86eb02a112550a0c65a74633.png)


如上图所示,就是一棵二叉查找树:**在此二叉查找树中,任意的子树都满足左子树结点数值 < 父结点数值 < 右子树结点数值**的规律。


### 2. 二叉查找树的操作


二叉查找树最简单的操作是结点查找,其次,因为整个二叉查找树都满足从左至右是有序的,因此如果二叉查找树的结点数量发生变化,就会引起二叉查找树需要重新调整的操作,所以,我们此处还会讨论二叉查找树新增结点和删除结点的操作,最后二叉查找树与普通二叉树一样,都可以进行最基本的遍历操作。


接下来,我们依次讨论:**结点查找、新增结点、删除结点、遍历二叉查找树。**


#### 2.1 结点查找


我们通过示例进行说明结点查找的逻辑,如下所示:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/809232da90d8427da0251964d5b95709.png)


上图中是一个二叉查找树,现在我们希望查找数值5所在的结点。其具体的步骤如下:


①. 访问根节点,根结点数值位7;


②. 要查找的数值5 < 7,因此访问结点7的左子树结点,并获得左子树结点数值4;


③. 要查找的数值5 > 4,因此访问结点4的右子树结点,并获得右子树结点数值6;


④. 要查找的数值5 < 6,因此访问结点6的左子树结点,并获得左子树结点数值5;


⑤. 要查找的数值5 == 5,因此表示找到了目标数值5所在的结点。


时间复杂度分析:假设一课二叉查找树结点的个数为n,我们会发现在进行查找时,总是会先判断要查找的数值和当前结点的数值的大小,然后根据判断结果,选择其中一侧进行继续查找;而不符合条件的另外一侧子树,可以直接放弃,因为我们知道二叉查找树从左至右总是有序的。这种从左至右有序的二叉查找树,在进行查找时,可以极大的节省时间。实际上,使用二叉查找树查找某个结点,所需要的**时间复杂度为O(log** **2** **n)** ,该时间复杂度与树的深度O(log2n)是一样的。


#### 2.2 新增结点


依然以上述二叉查找树为例,现在要插入数值为3的结点,示意图如下:


![](https://img-blog.csdnimg.cn/img_convert/7645e6933cfaeab1eb1cdd8e66bf8497.png)


**如上图,插入数值为3的结点的步骤如下:**


①. 访问根结点,获得根结点数值7;


②. 要插入结点的数值3 < 7,因此访问根结点的左子树,并获得左子树结点的数值4;


③. 要插入结点的数值3 < 4,因此访问根结点的左子树,并获得左子树结点的数值2;


④. 要插入结点的数值3 > 2,因此访问根结点的右子树,但右子树为空;


⑤. 右子树为空,即意味着找到了要插入的位置,即将新增的数值位3的结点作为结点2的右子树。


时间复杂度分析:根据插入的步骤,我们可以非常容易的理解插入结点的操作时间复杂度也为O(log2n),与查找结点时间复杂度相同。


#### 2.3 删除结点


删除结点的操作与前面的查找和增加操作不太一样,删除操作需要分不同的情况进行讨论,原因是删除操作会使二叉查找树的结点减少,删除后需要让剩余的结点继续满足二叉查找树的规则和特点,就可能需要做出调整。


具体的,我们可以将删除结点操作分为三种情况:删除叶子结点、删除结点有1个子树、删除结点有2个子树。下面,我们详细进行讨论:


##### 2.3.1 删除叶子结点


删除叶子结点是最简单的操作,因为叶子结点是最底层的结点,因此不需要任何的调整,直接删除即可。**删除叶子结点不会对二叉查找树的性质产生影响。**


##### 2.3.2 删除结点有1个子树


当要删除的结点有1个子树时(可能是左子树,也可能是右子树)。我们需要将删除结点的子树结点,替换到删除结点的位置。比如,以下图为例:


![](https://img-blog.csdnimg.cn/img_convert/5257bd91123493f097b999737c97b07a.png)


如上图所示,我们希望删除数值位6的结点。由于结点6有一棵数值位5的左子树。因此,在将结点6删除后,将子结点5放在原来结点6的位置上,如上右图所示。


通过上述案例操作我们可以总结:**当删除结点有1个子树结点时,直接将子结点放在删除结点的位置**。


##### 2.3.3 删除结点有2个子树


当删除结点有2个子树时,可以借助二叉树的中序遍历结果进行操作。具体步骤为:


(1). 找出二叉查找树的中序遍历序列;


(2). 找到要删除结点数值的前驱结点数值;


(3). 使用前驱结点数值替换删除的结点。


以下图为例:要删除二叉查找树的数值9所在的结点



**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)**
![img](https://img-blog.csdnimg.cn/img_convert/bafb4efd100ce4a1694ecf9546b065b9.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注网络安全)**
[外链图片转存中...(img-siNiMuNJ-1713546393290)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值