zoukankan      html  css  js  c++  java
  • [Data Structure] 二叉搜索树(Binary Search Tree)

    1. 二叉搜索树,可以用作字典,或者优先队列。

    2. 根节点 root 是树结构里面唯一一个其父节点为空的节点。

    3. 二叉树搜索树的属性:

      假设 x 是二叉搜索树的一个节点。如果 y 是 x 左子树里面的一个节点,则 y.key <= x.key。如果 y 是 x 右子树里面的一个节点,则 x.key <= y.key。

    4. 通过一次中序遍历 ( inorder tree walk ),可以将二叉搜索树的元素按照排好的顺序输出。例子如下

    1 INORDER-TREE-WALK(x)
    2     if x != NIL
    3         INORDER-TREE-WALK(x.left)
    4         print x.key
    5         INORDER-TREE-WALK(x.right)

    5. 二叉搜索树不仅支持搜索操作,还支持查找最小值、最大值、后继节点( successor )、前驱节点( predecessor )

    搜索,通过递归能轻易实现搜索操作.

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

    迭代版代码如下

    ITERATIVE-TREE-SEARCH(x, k)
        while x != NIL and k != x.key
            if x < 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

    节点 x 的后继节点,是值在树结构中比 x 大的最小节点。

    后继节点有两种情况

    a. 当节点 x 有右子树,则后继节点为右子树中最小值。

    b. 当节点 x 没有右子树并有后继节点,则 x 的后继节点为 x 的某个祖先节点,该祖先节点满足其左子节点也是 x 的祖先节点。也就是说,从 x 往 root 的父节点路径查找,第一个向右拐的目标节点(即,父节点),就是后继节点。

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

    前驱节点和后继节点的查找思路相似。

    6. 插入节点 x,有两个步骤:1) 搜索合适插入的位置 2) 插入元素。代码如下

    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

    7. 删除节点 x ,有下面三种情况

      a. 没有子节点,则直接删除

      b. 仅有一个子节点,则用子节点代替待删除节点。

      c. 有两个子节点,则找到 x 的后继节点 y。y 必然在 x 的右子树里面最左边的节点。然后,用 y 覆盖 x, 删除 y 原来的节点。由于 y 是右子树里最左边的节点,所以没有左字节,有或者没有右子节点,此时便是 a 或 b 的情况。

     下面是根据上面逻辑写代码实现。和书本的版本比起来,代码行数多些,不过可读性较好。

    TREE-DELETE(node)
        if node.left == NIL && node.right == NIL
            node.parent = NIL
            return
        if node.left != NIL && node.right != NIL
            newN = TREE-MINIMUM(node.right)
            node.key = newN.key
            TREE-DELETE(newN)
            return
        if node.left != NIL
            p = node.p
            s = node.left
            p.left = s
            s.p = p
            node.p = NIL
            node.left = NIL
        if node.right != NIL
            p = node.p
            s = node.right
            p.right = s
            s.p = p
            node.p = NIL
            node.right = NIL

    参考资料

    Binary search tree. Removing a node, algolist

    12 Binary Search Trees, Introduction to algorithms

    第 12 章 二叉搜索树,《算法导论》

  • 相关阅读:
    NSURLConnection和Runloop(面试)
    文件的上传
    CentOS 7防火墙快速开放端口配置方法
    国内常用源镜像地址:
    yum安装zabbix-web-mysql出现[Errno 256] No more mirrors to try.
    1251-Client does not support authentication protocol requested by server; consider upgrading MySQL client。
    http代理和SOCKS代理的区别
    windows下redis安装
    centeros7安装mysql
    nginx配置负载均衡分发服务器笔记
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5713268.html
Copyright © 2011-2022 走看看