Why need Binary Tree?

有时候,我们希望数据按照特定顺序排列。
比如:

  • 想要按字母顺序排列人名;
  • 按价格顺序排列产品;
  • ...

image

树也是节点结构

image

规定

  • 二叉树的每个节点的子节点数量都只能是0个 或1个、或2个;
  • 每个节点最多有一个左子节点和右子节点
  • 一个节点的左子树的值都 小于 节点本身,
  • 一个节点的右子树的值都 大于 节点本身;
  • 这一规律适用于所有节点。

术语

  • 层级
    image

  • 平衡
    image

树的创建

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)

image

树的查找

给你一颗二叉树,
image

需要查找61,

查找步骤:

  1. 算法开始时,根节点就是第一个“当前节点”;
    image
    检查当前节点的值,如果时这个值,那就找到了。

  2. 如果要找到值小于当前节点值,那么就在其左子树中继续查找。

  3. 如果要找的值大于当前节点的值,那么就在其右子树中继续查找。

image
image

查找的效率

每一步排除了大约一半的剩余节点,因此,二叉查找树的查找需要O(log N)时间。

树的删除

删除是最复杂的操作。

需要区分这几种情况:

  • 没有子节点;
  • 有一个子节点;
  • 有两个子节点;
  • 有多个子节点;

把所有步骤结合到一起,二又查找树的删除算法如下:

  • 如果要删除的节点没有子节点,那么就直接删除该节点。

  • 如果要删除的节点有一个子节点,那么就在删除该节点的同时把子节点插到该节点的位置。

  • 要删除有两个子节点的节点,需要把要删除的节点替换为其 后继 节点。后继节点就是 大于被删除节点的所有子节点中最小的那个。

    这个就是最复杂的情况,假设要图这颗树的56,
    image
    需要把要删除的节点替换为其 后继 节点。后继节点就是 大于被删除节点的所有子节点中最小的那个。这个有点绕口!
    换一个说法:如果按升序排列被删除节点及其后代,那么后继节点就是被删除节点的下一个数。
    image

  • 要删除的节点在树的顶端(也很复杂),寻找后继节点的算法如下:

  • 要寻找后继节点,需要先移动到被删除节点的右子节点,然后一直沿着左边的链接移动到左子节点,直到找不到任何左子节点为止。最下面的这个值就是后继节点。

  • 如果后继节点有一个右子节点,那么在把后继节点放到被删除节点的位置之后,把这个右子节点变成 后继节点曾经的父节点的左子节点。

二叉查找树(BST)的删除操作比较复杂,主要是因为在删除节点后需要保持树的性质,即每个节点的左子树都要小于它,右子树都要大于它。

适合场景

二叉查找树的查找、插入、删除效率都是(log N),因此,它很适合那些需要存储和操作有序数据的场合。

image

树的遍历

遍历树的方式有多种:

  • 中序遍历
  • ...

使用递归的方式去遍历树...

posted on 2024-09-19 11:31  Mysticbinary  阅读(15)  评论(0编辑  收藏  举报