• [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 章 二叉搜索树,《算法导论》

  • 相关阅读:
    jquery easyui DataGrid
    jquery-easyui中表格的行编辑功能
    C# 序列化与反序列化几种格式的转换
    ASP.NET中JSON的序列化和反序列化
    市委组织部考核项目——利用EasyUi中可编辑的DataGrid控件对多行数据进行编辑并提交
    easyui datagrid 添删改(纪录)
    easyui datagrid
    JS页面间传值
    JQuery下focus()无法自动获取焦点的处理方法 jquery如何使文本框获得焦点
    jQuery插件 -- Form表单插件jquery.form.js
  • 原文地址:https://www.cnblogs.com/TonyYPZhang/p/5713268.html
Copyright © 2020-2023  润新知