算法之路helloworld被隐藏了的过程首页投稿(暂停使用,暂停投稿)

二叉搜索树

2016-06-07  本文已影响263人  b64c74899092

二叉搜索树

搜索树结构支持许多动态集合操作,包括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

分两种情况:

查询过程和上面的操作一样也是简单路径。时间也是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

删除

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

为了在二叉搜索树中移动子树,定义一个子过程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
上一篇 下一篇

猜你喜欢

热点阅读