二叉查找树
二叉树包含许多特殊的形式,每一种形式都有自己的作用,但是其最主要的应用还在于进行查找操作和维持相对顺序这两个方面。
二叉查找树的定义(Binary Search Tree):
- 该树是一颗二叉树。
- 如果左子树不为空,则左子树上所有节点的值均小于根节点的值。
- 如果右子树不为空,则右子树上所有节点的值均大于根节点的值。
- 左、右子树也都是二叉查找树。
二叉查找树就是为了快速查找某个元素。
例如要查找值为1的结点,步骤如下:
第一步:毕竟1与根节点的值,结果1小于6,向右查找,找到6的右孩子值为3的结点。
第二步:比较1与3,发现1还是小于3,那么找到值为3的结点的右孩子2。
第三步:比较1与2,发现1还是小于2,那么查找到值为2的结点的右孩子。
第四步:发现1等于1,那么该结点就是我们所要查找的结点。
可以发现二叉查找树的时间复杂度为O(logn),和树的深度一样。
而且类似于二分查找(二分查找要求数组元素是有序的)。
二叉排序树
二叉查找树又被称为二叉排序树,因为二叉查找树的定义要求了左子树小于父结点,右子树大于父结点,保证了二叉树是有序的。
而新插入的结点同样要遵循这一要求,所以也是有序的。
例如,新插入一个结点值为5的元素,按照二叉排序树的规则,由于5<6,5>3,5>4,所以最终会插入到结点4的右孩子位置。
但如果有这么一种情况,插入的结点大部分是右孩子或者左孩子,那么该二叉排序树的查找时间就不再是O(logn)了,而是O(n)。
例如要查找结点值为9的结点,那么就需要遍历比较3、4、6、7、8结点的值,查询的时间复杂度大大提升了。
这种二叉树已经失去了平衡。
解决已经失去平衡的二叉树的方法有AVL树、红黑树等。
除此之外,还需要讲解说明下二叉排序树的删除结点操作。
当在二叉排序树中删除某个关键字时,不能把以该关键字所在的结点为根的子树都删除,而是只删除这一个结点,并保持二叉排序树的有序性。
加入要删除的结点为p,则删除结点p的过程分为如下三种情况:
- 第一种情况:p结点为叶子结点。直接删除,不会破坏二叉排序树的有序性。
- 第二种情况:p结点只有右子树而无左子树,或者只有左子树而无右子树(即被删除结点只有一棵子树的情况)。只需要将p结点的子树直接连接在原来p与双亲结点相连的指针上即可。
- 第三种情况:p结点既有左子树又有右子树。其步骤如下:
- 先沿着p结点的左子树根结点的右指针一直向右走,直到其右子树的最右边的一个结点r(也可以沿着p结点的右子树根结点的左指针一直向左走,直到来到其左子树的最左边的一个结点)。
- 然后将p结点中的关键字用r中的关键字替代。
- 最后判断r如果是叶子结点则按照第一种情况,如果r不是叶子结点,则按照第二种情况处理(此时的r不可能是有两个子树的结点)。
或者