二叉搜索树

作者: b64c74899092 | 来源:发表于2016-06-07 17:07 被阅读263次

二叉搜索树

搜索树结构支持许多动态集合操作,包括search,minimum,maximum,predecessor,successor,insert,delete等。使用一棵搜索树既可以作为一个字典,又可以作为一个优先队列。

什么是二叉搜索树

顾名思义,二叉搜索树就是以一棵二叉树来组织的。这样的一棵树可以用一个链表来表示,每一个结点都是一个对象,除了对象中的数据外,还有left,right,p,是分别指向当前结点的左孩子,右孩子和双亲的指针。如果不存在那么对应的值为nil。根结点是唯一父指针为nil的结点。

树中的关键字总是以某种性质的方式来存储:

当前结点的关键字大于等于左子树小于等于右子树。

这个性质让我们可以通过一个简单的递归算法来按序输出二叉搜索树种的所有关键字,这种算法就是中序遍历

中序遍历:递归遍历 左子树->根->右子树

先序遍历:递归遍历 根->左子树->右子树

后序遍历:递归遍历 左子树->右子树->根

中序遍历伪代码:

INORDER-TREE-WALK(x)
    if x != NIL
        INORDER-TREE-WALK(x.left)
        print x.key
        INORDER-TREE-WALK(x.right)
遍历一棵有n个结点的二叉搜索树需要

时间,因为初次调用之后,对于每一个结点这个过程都要自己调用两次:一次左孩子,一次右孩子。

查询二叉搜索树

经常需要查找一个存储在二叉搜索树中的关键字。

查找

输入一个指向树根的指针和一个关键字k,如果这个节点存在,返回一个指向k的结点指针,否则返回nil。

TREE-SEARCH(x,k)
    if x == NIL or k == x.key
        return x
    if k < x.key
        return TREE-SEARCH(x.left,k)
    else return TREE-SEARCH(x.right,k)

这个过程从根开始,沿着这棵树中的一条简单路径向下进行。所以运行时间为O(h),其中h是树的高度。

可以用while循环来展开递归,用一种迭代的方式重写这个过程。对于大多数计算机,迭代版本的效率要高得多。

ITERATIVE-TREE-SEARCH(x,k)
    while x != NIL and k != x.key
        if k < x.key
            x = x.left
        else x = x.right
    return x 

最大关键字好最小关键字

如果一个结点没有左子树,那么该结点就是最小关键字。没有右子树的就是最大关键字。

TREE-MINIMUM(x)
    while x.left != NIL
        x = x.left
    return x

TREE-MAXIMUM(x)
    while x.right != NIL
        x = x.right
    return x

和查找一样,过程也是一条简单路径,时间也是O(h)。

后继和前驱

如果给的关键字都不相同,那么一个结点的后继就是大于x.key的最小关键字结点。前驱就是小于x.key的最大关键字结点。

TREE-SUCCESSOR(x)
    if x.right != NIL
        return TREE-MINIMUM(x.right)
    y = x.p
    while y != NIL and x == y.right
        x = y
        y = y.p
    return y

分两种情况:

  • x的右子树非空,后继就是右子树的最左结点。
  • x的右子树为空,后继y就是x的某个祖先结点的父节点,而且祖先结点在y的左子树。

查询过程和上面的操作一样也是简单路径。时间也是O(h)。前驱操作和后继是对称的就不再写了。

插入和删除

插入

TREE-INSERT(T,z)
    y = NIL
    x = T.root
    while x != NIL
        y = x
        if z.key < x.key
            x = x.left
        else x = x.right
    z.p = y
    if y == NIL
        T.root = z
    elseif z.key < y.key
        y.left = z
    else y.right = z

删除

删除比插入要复杂,可以分为三种情况:

  • 如果z没有孩子,那么就可以简单的删除,然后修改它的父节点,用NIL来代替z
  • 如果只有一个孩子,那么将孩子提升到z的位置,然后修改父节点,用z的孩子来代替z
  • 如果有两个孩子,那么寻找z的后继y,让y占据z的位置。z的右子树成为y的右子树,z的左子树成为y的左子树。

为了在二叉搜索树中移动子树,定义一个子过程TRANSPLANT。

TRANSPLANT(T,u,v)
    if u.p == NIL
        T.root = v
    elseif u == v.p.left
        u.p.left = v
    else u.p.right = v
    if v != NIL
        v.p = u.p

删除:

TREE-DELETE(T,z)
    if z.left == NIL
        TRANSPLANT(T,z,z.right)
    elseif z.right == NIL
        TRANSPLANT(T,z,z.left)
    else y = TREE-MINIMUM(z.right)
        if y.p != z
            TRANSPLANT(T,y,y.right)
            y.right = z.right
            y.right.p = y
        TRANSPLANT(T,z,y)
        y.left = z.left
        y.left.p = y

相关文章

  • 数据结构与算法之二叉搜索树(八)

    目录 二叉搜索树概念二叉搜索树的接口设计,包括增,删,改,查平衡二叉搜索树 一 二叉搜索树 二叉搜索树是二叉树的一...

  • Algorithm小白入门 -- 二叉搜索树

    二叉搜索树二叉搜索树 BSTBST 的基本操作计算合法的 BST 1. 二叉搜索树 BST 二叉搜索树(Binar...

  • 二叉搜索树

    二叉搜索树 图解二叉树搜索算法图解:二叉搜索树算法二叉查找树(Binary Search Tree),(又:二叉搜...

  • 23-红黑树

    1.二叉搜索树(BST)继承二叉树(BinaryTree) 2.平衡二叉搜索树(BBST)继承二叉搜索树(BST)...

  • 二叉搜索树(Binary Search Tree)

    1. 定义 二叉搜索树(BST)又叫二叉查找树,二叉排序树。二叉搜索树就是一棵二叉树,但是它又具有搜索树的特征: ...

  • 二叉树基础

    二叉树的分类 完全二叉树与满二叉树 二叉搜索树BST 平衡二叉搜索树BBST因为二叉搜索树有可能退化为链表,降低查...

  • 数据结构 经典算法复习

    二叉搜索树, 平衡二叉树(AVL) 红黑树 B树(平衡多路搜索树) B+树(在B树上改造) 二叉搜索树...

  • Swift 验证二叉搜索树- LeetCode

    题目: 验证二叉搜索树 验证二叉搜索树给定一个二叉树,判断其是否是一个有效的二叉搜索树。 假设一个二叉搜索树具有...

  • 树,二叉树,搜索树

    树,二叉树,搜索树 资料 二叉搜索树 Demo 树的遍历 Demo 题目 ◎ 二叉树的中序遍历 ◎ 二叉树...

  • 【数据结构】红黑树

    1、什么是红黑树? 红黑树是一个要求不那么严格的平衡二叉树搜索树(平衡二叉搜索树/AVL树=平衡二叉树+二叉搜索树...

网友评论

    本文标题:二叉搜索树

    本文链接:https://www.haomeiwen.com/subject/frnddttx.html