• 算法导论 第三部分——基本数据结构——二叉搜索树


    一、什么是二叉搜索树

      二叉查找树是按照二叉树结构来组织的,因此可以用二叉链表结构表示。二叉查找树中的关键字的存储方式满足的特征是:设x为二叉查找树中的一个结点。如果y是x的左子树中的一个结点,则key[y]≤key[x]。如果y是x的右子树中的一个结点,则key[x]≤key[y]。根据二叉查找树的特征可知,采用中根遍历一棵二叉查找树,可以得到树中关键字有小到大的序列。

    二叉树的查找、最大/小、前驱和后继的伪代码: 复杂度都是 h

    //search  递归版
    TREE_SEARCH(x,k)
      if x=NULL or k=key[x]
          then return x
      if(k<key[x])
          then return TREE_SEARCH(left[x],k)
       else
          then return TREE_SEARCH(right[x],k)
    
    //search 迭代版
    ITERATIVE_TREE_SEARCH(x,k)
      while x!=NULL and k!=key[x]
          do if k<key[x]
                  then x=left[x]
               else
                  then x=right[x]
       return x
    
    //最小指
    TREE_MINMUM(x)
        while left[x] != NULL
           do x=left[x]
        return x
    
    //最大值
    TREE_MAXMUM(x)
        while right[x] != NULL
            do x= right[x]
         return x
    
    //后继
    TREE_PROCESSOR(x)
    // 右孩子非空,返回右子树的最小值
        if right[x] != NULL
            then return TREE_MINMUM(right(x))
    // 右孩子为空,向上找后继
        y=parent[x]
        while y!= NULL and x ==right[y]
               do x = y
                   y=parent[y]
        return y

    二叉树的插入和删除 复杂度均为 h

    插入和删除会引起二叉查找表示的动态集合的变化,难点在在插入和删除的过程中要保持二叉查找树的性质。插入过程相当来说要简单一些,删除结点比较复杂。

    (1)插入

      插入结点的位置对应着查找过程中查找不成功时候的结点位置,因此需要从根结点开始查找带插入结点位置,找到位置后插入即可。下图所示插入结点过程:

    书中给出了插入过程的伪代码:

    TREE_INSERT(T,z)
        y = NULL;
        x =root[T]
        while x != NULL
            do y =x
                if key[z] < key[x]
                     then x=left[x]
                     else  x=right[x]
         parent[z] =y
         if y=NULL
            then root[T] =z
            else if key[z]>key[y]
                       then  keft[y]  = z
                       else   right[y] =z

    (2)删除

      从二叉查找树中删除给定的结点z,分三种情况讨论:

    <1>结点z没有左右子树,则修改其父节点p[z],使其为NULL。删除过程如下图所示:

    <2>如果结点z只有一个子树(左子树或者右子树),通过在其子结点与父节点建立一条链来删除z。删除过程如下图所示:

    <3>如果z有两个子女,则先删除z的后继y(y没有左孩子),在用y的内容来替代z的内容。

    书中给出了删除过程的伪代码:

    TREE_DELETE(T,z)
        if left[z] ==NULL or right[z] == NULL
           then y=z
           else  y=TREE_SUCCESSOR(z)
       if left[y] != NULL
           then x=left[y]
           else  x=right[y]
       if x!= NULL
           then parent[x] = parent[y]
       if p[y] ==NULL
          then root[T] =x
          else if y = left[[prarnt[y]]
                      then left[parent[y]] = x
                      else  right[parent[y]] =x
        if y!=z
            then key[z] = key[y]
                  copy y's data into z
         return y
  • 相关阅读:
    阶段1 语言基础+高级_1-2 -面向对象和封装_2面向对象思想的举例
    阶段1 语言基础+高级_1-2 -面向对象和封装_1面向对象思想的概述
    2-3 【初识组件】顶部 TabBar
    2-2 工程源码文件结构
    Fragment状态保存
    【51单片机】六种亮灯方式
    Hadoop自学笔记(二)HDFS简单介绍
    lvs 负载均衡环境搭建
    [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第十一章 属性
    说说nio----1
  • 原文地址:https://www.cnblogs.com/NeilZhang/p/5654393.html
Copyright © 2020-2023  润新知