Why need Binary Tree?
有时候,我们希望数据按照特定顺序排列。
比如:
- 想要按字母顺序排列人名;
- 按价格顺序排列产品;
- ...
树也是节点结构
规定
- 二叉树的每个节点的子节点数量都只能是0个 或1个、或2个;
- 每个节点最多有一个左子节点和右子节点;
- 一个节点的左子树的值都 小于 节点本身,
- 一个节点的右子树的值都 大于 节点本身;
- 这一规律适用于所有节点。
术语
-
层级
-
平衡
树的创建
class TreeNode:
def _init_(self, val, left=None, right=None):
self.value = val
self.leftChild = left
self.rightChild = right
构建一棵简单的树:
node1 = TreeNode(25)
node2 = TreeNode(75)
root = TreeNode(50, node1, node2)
树的查找
给你一颗二叉树,
需要查找61,
查找步骤:
-
算法开始时,根节点就是第一个“当前节点”;
检查当前节点的值,如果时这个值,那就找到了。 -
如果要找到值小于当前节点值,那么就在其左子树中继续查找。
-
如果要找的值大于当前节点的值,那么就在其右子树中继续查找。
查找的效率
每一步排除了大约一半的剩余节点,因此,二叉查找树的查找需要O(log N)时间。
树的删除
删除是最复杂的操作。
需要区分这几种情况:
- 没有子节点;
- 有一个子节点;
- 有两个子节点;
- 有多个子节点;
把所有步骤结合到一起,二又查找树的删除算法如下:
-
如果要删除的节点没有子节点,那么就直接删除该节点。
-
如果要删除的节点有一个子节点,那么就在删除该节点的同时把子节点插到该节点的位置。
-
要删除有两个子节点的节点,需要把要删除的节点替换为其 后继 节点。后继节点就是 大于被删除节点的所有子节点中最小的那个。
这个就是最复杂的情况,假设要图这颗树的56,
需要把要删除的节点替换为其 后继 节点。后继节点就是 大于被删除节点的所有子节点中最小的那个。这个有点绕口!
换一个说法:如果按升序排列被删除节点及其后代,那么后继节点就是被删除节点的下一个数。
-
要删除的节点在树的顶端(也很复杂),寻找后继节点的算法如下:
-
要寻找后继节点,需要先移动到被删除节点的右子节点,然后一直沿着左边的链接移动到左子节点,直到找不到任何左子节点为止。最下面的这个值就是后继节点。
-
如果后继节点有一个右子节点,那么在把后继节点放到被删除节点的位置之后,把这个右子节点变成 后继节点曾经的父节点的左子节点。
二叉查找树(BST)的删除操作比较复杂,主要是因为在删除节点后需要保持树的性质,即每个节点的左子树都要小于它,右子树都要大于它。
适合场景
二叉查找树的查找、插入、删除效率都是(log N),因此,它很适合那些需要存储和操作有序数据的场合。
树的遍历
遍历树的方式有多种:
- 中序遍历
- ...
使用递归的方式去遍历树...