主要介绍以下几个部分:
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