3. 二叉搜索树 --- BST(Binary Search Tree)

BST : 二叉搜索树 树表结构查找相关算法

主要思想 : 循关键码访问 key
  • 条件 : 关键码之间
    1. 大小比较
    2. 相等比对

顺序性(标准定义) : L <= V <= R
为简化起见,规定BST中不允许(禁止)重复词条
故有定义 : L < V < R
这种简化 : 应用中不自然,算法上也无必要
###
如果一定要存在重复的词条,则需要做一些规定,防止插入一个已存在的词条,是插在存在的节点的左子树还是右子树中?
在此规定: 插入重复的词条,统一插到search()到的第一个已存在的重复节点的右子树中(因为当前的 BST 中可能存在多个重复词条节点)

BST中序遍历序列,必须单调非降;这是 BST的充要条件。


BST 作为动态查找(搜索)算法 : 查找过程中涉及插入和删除基本,在插入和删除动作执行时,不能改变 BST充要条件特性,所以 BST 的插入和删除节点的操作与标准的二叉树插入和删除节点的操作有所不同,涉及插入或删除后的 BST 的调整操作。

BST 插入或删除节点后不满足 BST性质,需要调整,满足终须单调非降性质



BST常用接口

1. 接口声明 :
BinNodePosi Search(const T &);      //查找
BinNodePosi Insert(const T &);      //插入节点操作
BinNodePosi Remove(const T &);      //删除节点操作
/* 删除节点操作后的调整动作  */
/* 1. <3+4重构> */
BinNodePosi connect34(BinNodePosi, BinNodePosi, BinNodePosi,
                      BinNodePosi, BinNodePosi, BinNodePosi, BinNodePosi);

/*2. <旋转操作> */
BinNodePosi rotateAt(BinNodePosi);
/* 非常有用的一个记录值 */
BinNodePosi _hot;  

// 作为记录 Search() 命中节点的父亲 或 未找到时最后一个访问的节点
// 记录这个 _hot 以便于插入和删除操作!!!
2. 算法及其实现
2.1 BST查找算法实现 Search()
/*
BinNodePosi &v         当前树(子树)根节点,以 v 节点为根节点
const T &e             目标关键码
BinNodePosi &hot      记忆热点,插入、删除操作时很有用!!!作为父指针记忆
*/
BinNodePosi BST_Search(BinNodePosi &v, const T &e, BinNodePosi & hot)
{
    if ( !v || ( e== v->data))                       // 出口
    {
        return v;
    }

    hot = v;                                        // 记录当前节点
    if( e < v->data)
    {
        return BST_Search( v->lchild, e, hot);      //左子树递归搜索    
    }
    else
    {
        return BST_Search( v->rchild, e, hot);     //右子树递归搜索
    }
}/* 典型的尾递归,可改成迭代版实现 */
// 运行时间正比于返回节点 v 的深度,不超过树高O(h);

BinNodePosi Search(const T &e)
{
    return BST_Search(_root, e, _hot=NULL);
}


/*******************************************************************/
/*******************************************************************/
/* BST_Search() 非递归实现 */
BinNodePosi BST_Search2(BinNodePosi &v, const T &e, BinNodePosi & hot)
{
    BinNodePosi p = v;

    while(NULL != p)
    {
        if (e == p->data)
        {
            return p;
        }
      
        hot = p;   // 记录当前节点,执行下面的插入和删除动作时,hot 非常有用
        
        if ( p->data < e)
        {
            p = p->rchild;
        }
        else
        {
            p = p->lchild;
        }
    }

    return p;      //未找到, p == NULL
}
2.2 BST 插入算法实现
  • × 先借助 Search(value) 确定待插入值 value 的插入位置及方向,再将新节点作为叶子插入
  • × 若 value 尚不存在,则 _hot 为新结点的 父亲
    v = Search(value)_hot 对新孩子的引用;[ Search(value)本为空,V节点作为其引用 ]
    Search(value)

实例 : 执行 insert(40)

BST-Insert过程图解

BST 插入算法实现 Code

后补


2.3 BST 删除算法实现

实现步骤:

  • 定位待删除节点 : search(e)
  • 确定目标节点是否存在,存在执行下面步骤;不存在,返回错误;
  • 两类情况实施删除操作,并作出对应的调整操作
  • 更新树的规模 (size 和 _hot节点及其历代祖先的高度)
/* remove()  代码实现  Code */

bool remove(const T &e)
{
    BinNodePosi  &x = Search(e);    //step 1
    if (!x)
        return false;              // step 2
    
    removeAt(x , _hot);            // step 3

    _size --;                      // step 4
    updateHeightAbove(_hot);    

    return true;
}


删除操作 removeAt() 分以下两种情况分析实现

假设待删节点为 x

1. 情况一 :

若 x 的 某一子树为空 ,则可将待删节点 x 替换为其另一个子树; 【即 直接将 x节点 的子树替换 x 节点

验证 : 拓扑结构未变;见下图。

示例:

待删节点 x 某一子树为空 - remove图解示例

情况一 代码实现

2. 情况二 :

x 左右子树都存在(非空),删除调整怎么做?
采取的解决策略: 化繁为简 (化为情况一,然后按情况一解决)

算法步骤

  • Step 1 : 找中序遍历下的 x 的 直接后继交换两者 swap
  • Step 2 :此时交换后删除 x 节点,变成情况一,执行一的相关操作即可

示例 :


待删除节点x 左右子树都存在 - remove图解示例

情况二 代码实现


BST的删除操作的复杂度 O(h); [ h 为树高 ]

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容