二叉查找树

局部搜索

定义:一个局部搜索数据结构存储一系列元素,每个元素具有对应的一个键值,这些键值属于某个具有一定顺序的集合.它支持以下操作:

  • RangeSearch(x, y):返回所有在x,y之间的数
  • NearestNiborghbors(z):返回键值和z最相近对应的元素
  • Insert(x):添加键值为x的元素
  • Delete(x):删除键值为x的元素

由于哈希表,数组,排序数组,链表不能实现上述操作(有的可以,但是时间复杂度不符合),要 使用新的数据结构实现——二叉搜索树

搜索树的性质:

x的键值大于它任意左子树元素的键值,小于任意有右子树元素的键值.

基本操作:

Find

输入:键值k,根节点R
输出:根节点为R的树中键值为k的结点
伪代码实现

Find(k,R)
//如果k等于结点的键值,返回该结点
if R.key == k:
    return R
//若k小于根节点的键值,则在根节点的左子树中查找
else if R.key > k:
    if R.Left != null:
        return Find(k, R.Left)
    //若找不到,则返回和要找键值最相近的结点(此时k要存在,应该是此节点的左孩子
    return R
//若k大于节点的键值,则在结点的右子树中查找
else if R.key < key:
    if R.Right != null:
        return Find(k, R.Right)
    //若找不到,则返回和要找键值最相近的结点(此时k要存在,应该是此节点的右孩子
    return R

Next

输入:结点N
输出:键值大于N结点中键值最小的结点

分两种情况:

  • 结点N有右孩子结点
    返回的结点为右孩子结点的左子树的最后一个左孩子结点
  • 结点N没有右孩子结点
    返回的结点为V,其中V.Left = N

伪代码实现

Next(N)
//若N有右孩子结点
if N.right != null:
    return LeftDescendant(N.Right)
//若N没有右孩子结点
else:
    return RightAncestor(N.Left)


//递归寻找N右孩子结点左子树的左孩子结点
LeftDescendant(N)
    if N.Left == null:
        return N
    else:
        return LeftDescendant(N.Left)

//递归寻找大于N结点键值的父母结点(祖先结点)
RightAncestor(N)
     if N.key < N.parent.key:
         return N.parent
      else:
          return RightAncestor(N.parent)

RangeSearch

输入:键值x,y和根节点R
输出:键值在x,y之间的系列结点

伪代码实现

L <--- NULL
//找到键值为x的结点
N <--- Find(x,R)
while N.key <= y:
    if N.key >= x:
        L <--- L.append(N)
    //找出大于N结点键值的最小结点
    N <--- Next(N)
return L

Insert

输入:键值k和根节点R
输出:添加键值为k的结点到树中

伪代码实现

Insert(k, R)
p <--- Find(k, R)
Add new node with key k as child of the tree

Delete

输入:结点N
输出:把结点N从书中移除
伪代码实现

Delete(N)
if N.Right == null:
    Remove N,promote N.Left()
else:
    x <--- Next(N)
replace N by x,promote x.Right

Merge

输入两棵树S和T,其中S中的所有元素均小于T中的元素,返回包含S和T所有元素的一颗树
伪代码实现

Merge(R1, R2)
    //找出R1中最大的元素,作为生成树的根节点
    T <--- Find(max,R1)
    Delete(T)
    MergeWithRoot(R1, R2, T)
    return T

//两棵树,与根节点T合成一棵树
MergeWithRoot(R1, R2, T)

MergeWithRoot(R1, R2, T)
    T.Left <--- R1
    T.Right <--- R2
    R1.parent <--- T
    R2.parent <--- T
    return T

Split

给定一棵树和键值k,返回两棵新树R1和R2:其中R1的所有元素均小于或等于x,R2的所有元素均大于x
伪代码实现

Split(R, x)
    if R == null:
         return (null, null)
    if x <= R.key:
        (R1, R2) <--- Split(R.Left, x)
        R3 <--- MergeWithRoot(R1, R.Right, R)
        return (R1, R3)
    if x >= R.key:
        (R1, R2) <--- Split(R.Right, x)
        R3 <--- MergeWithRoot(R1, R.Left, R)
        return (R3,R2)   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值