一:二叉树
1.二叉树的定义
二叉树是几个有限无素的集合,该集合或
者为空、或者由一个称为根(root)的元
素及两个不相交的、被分别称为左子树和
右子树的二叉树组成,是有序树。当集合
为空时,称该二叉树为空二叉树。在二叉
树中,一个元素也称作一个节点 。
如图即为一个二叉树(可根据图片理解):
注:该树并不为一棵二叉搜索树
2.二叉树的遍历(深度优先遍历)
对于二叉树的遍历,可进一步分为三种:
①前序遍历(根左右):对于每一棵子树,先访问该节点,然后是左子树,最后是右子树
②中序遍历(左根右):对于每一棵子树,先访问左子树,然后是该节点,最后是右子树
③后序遍历(左右根):对于每一棵子树,先访问左子树,然后是右子树,最后是该节点
二:二叉查找树
1.二叉查找树的定义
二叉查找树,也称二叉搜索树或二叉排序树,是指一棵空树或者具有下列性质的二叉树:
①若任意节点的左子树不空 则左子树上所有结
点的值均小于它的根结点的值;
②若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
如图即为一棵二叉查找树:
(下面的二叉搜索树都以此树为例)
三:二叉查找树的代码实现
1.节点的创建:
二叉树的节点分位两类:
①树节点:该节点的左右孩子至少存在一个
对于该节点,包含有Value值,leftTreeNode左孩子以及rightTreeNode右孩子
②叶子节点:该节点没有左右孩子
对于该节点,只包含Value值
因此创建节点,我们要包含有两种实参构造,一种只有Value值,另一种均含有
下面我们来创造一个节点的标准Javabean类
我们还需创造一个BinaryTree类,我们需要有root成员变量,在该类中我们将实现遍历,插入,查找,删除等操作。
2.层序遍历
在开始写二叉树的三种基本遍历前,我们先了解一下层序遍历。
那什么是层序遍历呢?顾名思义,层序遍历就是对每一层的节点,从左到右以此遍历。下面我们来实现下它的代码。
形式一:
思路:对于每一层的节点,我们输出该点,再将它的左右孩子存起来,等这一层的节点遍历完成后,再对它的孩子节点重复此操作。
这样的输出就是我们要遍历的结果
对此你想到了用什么来实现该操作吗?(队列(先进先出))
下面我们来填入数据运行爽一下吧。
你们的是不是也是这样的结果呢?
形式二:
层序遍历当然要每一次分开来单独遍历,那我们能不能像下面这样的形式遍历呢?
下面我们就来实现一下吧!
思考:为什么队列的长度就是每一层要遍历的节点数呢?
第一次while循环: size等于1,for循环一次,出队一个节点,入队两个节点
第二次while循环: size等于2, for循环两次,出队两个节点,入队三个节点
.....
由此可得出为什么队列的长度会与每一层要遍历的节点数相同
3.前序,中序,后序遍历--递归实现
对于二叉树来说,递归是最常见最简单的解决问题的使用方法
注:二叉搜索树中序遍历后,数据为升序排列
4.前序,中序,后序遍历--非递归实现
对于二叉树来说,递归实现遍历太简单了,想要提高自己对于二叉树的理解,使用非递归来解决问题是最有效的方法
①前序,中序遍历
思路:从根节点开始一直向左遍历,直到该节点为空,获取前一个节点,开始遍历它的右子树
思考:这里我们要考虑的是,如何才能获取之前所遍历过的节点呢?(栈(先进后出))
中序遍历同后序遍历一样,只不过是处理Value值的地方不同而已。
②后序遍历
后序遍历同前序 中序遍历一样,都是需要依靠栈来实现的。但不同的是,前中序遍历到左子树为空时,直接出栈获取到前一个节点。而后序遍历需要我们,当左右子树都遍历完成时,再输出该节点的value值(左右根),这样我们就不能直接将左子树为空时的前一个节点出栈。
思路:一直遍历左子树,直到左子树为空时,获取左子树为空时的前一个节点,但不出栈,判断获取的节点的右子树是否遍历完成后,再输出该节点的value值(当该节点的右子树为空或者右子树遍历完成)
思考:我们如何知道右子树是否遍历完成了?再去输出该节点的value值。
当该节点的右子树等于最近一次出栈的节点时,就表示右子树已经遍历完成了。
怎么理解这句话呢?(我们只要知道,节点出栈的话就表示该节点以及它的左右孩子(根左右)已经遍历完成了)
5.插入节点insert
思路:①当树为空时,直接插入
②当树不为空时,如果所插入的值小于寻找节点的值,则向寻找节点的左子树寻找,大于反之。
6.查找节点find
思路:要插入的值与寻找节点的值比较,小于向左子树寻找,大于向右子树寻找,找到空节点时插入
7.删除节点remove
要删除的节点分为三种情况:
①第一种:要删除的节点有左右两个孩子
②第二种:要删除的节点只有一个孩子
③第三种:要删除的节点没有孩子
这里我们先考虑②③种情况:
如果我们要删除该节点,就需要知道该节点的父亲节点与孩子节点,再将父亲节点的指针指向孩子节点就完成了删除。
针对于③情况:
这里我们要思考:它的父亲节点只能指向一个节点,要删除该节点,它的左右孩子怎么办呢?
这里我们看中序遍历(所遍历的二叉搜索树为升序)
我们先看一组数据:1 2 3 4 6 7
我们要删除3,可以用2或者4代替它原来的位置
删除6,可以用4或者7代替它原来的位置
据此,那我们要删除该节点是不是也可以找一个合适的节点代替它的位置,然后再删除代替节点在树中的位置即可(删除代替节点就转换为③)
思路:首先要找到删除节点所在树中的位置
从第③种情况(左右孩子均存在)开始考虑起
记录父亲节点与孩子节点,最后将父亲节点的指针指向孩子节点
8.结果显示
三种遍历,插入,查找,删除等代码已经写好了,那我们就带入数据运行一下吧!
①遍历
②插入,删除,查找
四:二叉树必刷题目(根据自己情况)
①力扣101对称二叉树
递归
②力扣104最大深度
方法一:递归
方法二:后序遍历栈的最高值就是最大深度
方法三:层序遍历所遍历的层数就是最大深 度
③力扣111最小深度
方法一:递归
方法二:层序遍历到最低叶节点就是最小深度
④力扣226翻转二叉树
递归
⑤力扣938二叉搜索树范围和
方法一:中序遍历
方法二:上下界递归
⑥力扣98二叉搜索树是否合法
方法一:中序遍历(非递归)
方法二:中序遍历(递归)
方法三:上下界递归
注:若存在错误,不足之处,望各位指出修改₍˄·͈༝·͈˄*₎◞ ̑̑