算法导论--第十四章【数据结构的扩张】14.1

主要介绍以下几个部分:
1)在一颗红黑树上求第i小数是多少
需要在节点结构种增加一个域size,用来保存该节点中有几个内节点(包括当前节点)


OS-SELECT(root[T], i)
  r = size[left[x]] + 1                                             //左子树节点树+1,用于判断在左子树找还是右子                                                                            //树,或者就是当前节点
  if r == i
    return x                                                        //就是当前节点
  else i < r
    return OS-SELECT(left[x], i)
  return OS-SELECT(right[x], i-r)                       //右子树中寻找,需要减去左子树的节点数

 



2)给定一个节点x,求这个节点在中序遍历中得位置

OS-RANK(T,x)
  r = size[left[x]] + 1                                             //保证r的值为当前节点在树的中序遍历中的位置
  y = x
  while y!=root[T]
    if y == right[p[y]]                                          //如果y是右子树则需要加上左子树的节点数才行
                                                                                   // 如果是左子树就不需要加,因为右子树和父节点都
                                                                                   //不优先于它
      r = r + size[left[p[y]]] + 1
    y = p[y]
  return r

 

习题
14.1-3

OS-SELECT(x, i)
  r = size[left[x]] +1
  while (i !=r ) {
    if (i < r)
      x = left[x]
      r = size[left[x]] +1
    else
      x = right[x]
      r = size[left[x]] + 1
      i = i - r
  }
  return x

 

14.1-5

OS-SELECT-SUCCEED(T, x, i)
  r = OS-RANK(T, x)
  return OS-SELECT(root[T], r+i)

 

14.1-6
插入时,若插入i节点的左子树,则size+1,若是右子树则不变
删除时同理
14.1-7
逆序对的定义见wiki传送门,常规求逆序对的做法是用归并排序,复杂度也是O(nlgn)
这里可以用顺序统计树的结构来解决,假设一个集合{1,3,7,4,5,9}
求4的逆序对就是在1,3,7中寻找比4大得数,结果为1
4的index为j,前几个数得index为i,当
j > i && a[j]<a[i] 时满足条件,那么在顺序统计树中,j是插入的顺序,而第二个条件可以通过a[j]在
前三个数中得排名来得到也就是通过OS_KEY_RANK这个函数来得到,那么结论就是
result += j+1-OS_KEY_RANK(T,j)

我的个人博客: http://www.yancey.info/?p=145

posted @ 2013-11-08 00:47  Yancey咖啡  阅读(1567)  评论(0编辑  收藏  举报