思考题14-1
a) 设最大重叠点不是重叠区间的任意一个区间的端点。令
p
是最大重叠区间为
b) 按照树中的建议,使用红黑树,并且关联左右端点。
设
e1,e2,...,en
表示所有区间端点经过排序后的序列,令
s(i,j)=p(ei)+p(ei+1)+...+p(ej),其中1≤i≤j≤n
,我们希望找到一个
i
使
对树中的结点
x
,令
现在有以下计算公式:
对于
INTERVAL-INSERT
,我们插入区间的两个端点;
对于
FIND-POM
,我们返回
T.root.o
因为我们对所有的端点都插入到一颗红黑树中,然后用来求解 T.root.o ,所以不用删除树中的任何结点。
由定理14.1知时间复杂度为 O(lgn) ,实际上
FIND-POM
只需
O(1)
时间。
思考题14-2
a) 建立一个循环链表,链表中每个结点包括关键字和下一个结点信息,建表时间是
O(n)
,然后从头开始,每计数到
m
时删掉链表中的一个元素,总时间是
b) 直接使用第14.1节中的顺序统计树,假设现在还剩
k
个人,然后要被移除的是在剩余的人中排名第
JOSEPHUS(n,m)
initialize T to be empty
for j = 1 to n
create a node x with x.key == j
OS-INSERT(T, x)
k = n
j = m
while k >= 2
x = OS-SELECT(T.root, j)
print x.key
OS-DELETE(T, x)
k = k - 1
j = ((j + m - 2) mod k) + 1
print OS-SELECT(T.root, 1).key
最后的运行时间 O(nlgn) 。
附上代码
1、循环单链表
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
struct node_t
{
int key;
node_t *next;
};
int main()
{
int n,m;
cout << "Input n and m: ";
cin >> n >> m;
cout << endl;
if(n < 1)
return -1;
//建立循环链表
node_t *head = new node_t;
head->key = 1;
node_t *cur = head;
for(int i = 2; i <= n; ++i)
{
node_t *node = new node_t;
node->key = i;
cur->next = node;
cur = node;
}
cur->next = head;
//模拟退出
node_t *pre = cur;//开始时cur是第一个,pre是最后一个
cur = head;
while(cur->next != cur)
{
for(int i = 1; i < m; ++i)//找到第m个人
{
pre = cur;
cur = cur->next;
}
pre->next = cur->next;
cout << cur->key << ' ';
delete cur;
cur = pre->next;
}
cout << cur->key << endl;//打印最后一个
delete cur;
return 0;
}
2、顺序统计树
#include <iostream>
#include <climits>
#include <iomanip>
using std::cout;
using std::endl;
using std::cin;
enum COLOR
{
RED = 0,BLACK = 1
};
struct OS_RB_TREE
{
int key;
int size;
COLOR color;
OS_RB_TREE *parent;
OS_RB_TREE *left;
OS_RB_TREE *right;
};
OS_RB_TREE nil = {INT_MIN,0,BLACK,NULL,NULL,NULL};//哨兵
void LEFT_ROTATE(OS_RB_TREE **root,OS_RB_TREE *x)
{
if(x->right != &nil)
{
OS_RB_TREE *y = x->right;
x->right = y->left;
if(y->left != &nil)
y->left->parent = x;
y->parent = x->parent;
if(x->parent == &nil)
*root = y;
else if(x == x->parent->left)
x->parent->left = y;
else x->parent->right = y;
y->left = x;
x->parent = y;
y->size = x->size; //更新size
x->size = x->left->size + x->right->size + 1;
}
}
void RIGHT_ROTATE(OS_RB_TREE **root,OS_RB_TREE *x)
{
if(x->left != &nil)
{
OS_RB_TREE *y = x->left;
x->left = y->right;
if(y->right != &nil)
y->right->parent = x;
y->parent = x->parent;
if(x->parent == &nil)
*root = y;
else if(x == x->parent->left)
x->parent->left = y;
else x->parent->right = y;
y->right = x;
x->parent = y;
y->size = x->size;
x->size = x->left->size + x->right->size + 1;
}
}
OS_RB_TREE *SEARCH(OS_RB_TREE *root,int key)
{
if(root == &nil || root->key == key)
return root;
else if(root->key > key)
return SEARCH(root->left,key);
else return SEARCH(root->right,key);
}
OS_RB_TREE *MINIMUM(OS_RB_TREE *x)
{
if(x == &nil || x->left == &nil)
return x;
else return MINIMUM(x->left);
}
OS_RB_TREE *MAXIMUM(OS_RB_TREE *x)
{
if(x == &nil || x->right == &nil)
return x;
else return MAXIMUM(x->right);
}
OS_RB_TREE *SUCCESSOR(OS_RB_TREE *x)
{
if(x == &nil)
return x;
if(x->right != &nil)
return MINIMUM(x->right);
OS_RB_TREE *y = x->parent;
while(y != &nil && x == y->right)
{
x = y;
y = y->parent;
}
return y;
}
OS_RB_TREE *PREDECESSOR(OS_RB_TREE *x)
{
if(x == &nil)
return x;
if(x->left != &nil)
return MAXIMUM(x->left);
OS_RB_TREE *y = x->parent;
while(y != &nil && x == y->left)
{
x = y;
y = y->parent;
}
return y;
}
void OS_RB_TREE_INSERT_FIXUP(OS_RB_TREE **root,OS_RB_TREE *z)
{
while(z->parent->color == RED)
{
if(z->parent == z->parent->parent->left)
{
OS_RB_TREE *y = z->parent->parent->right;
if(y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else
{
if(z == z->parent->right)
{
z = z->parent;
LEFT_ROTATE(root,z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
RIGHT_ROTATE(root,z->parent->parent);
}
}
else
{
OS_RB_TREE *y = z->parent->parent->left;
if(y->color == RED)
{
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
}
else
{
if(z == z->parent->left)
{
z = z->parent;
RIGHT_ROTATE(root,z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
LEFT_ROTATE(root,z->parent->parent);
}
}
}
(*root)->color = BLACK;
}
void OS_RB_TREE_INSERT(OS_RB_TREE **root,int key)
{
OS_RB_TREE *y = &nil;
OS_RB_TREE *x = *root;
while(x != &nil)
{
y = x;
y->size += 1; //根到插入结点路径上每个结点size都加1
if(x->key > key)
x = x->left;
else x = x->right;
}
OS_RB_TREE *z = new OS_RB_TREE;
z->parent = y;
if(y == &nil)
*root = z;
else if(key < y->key)
y->left = z;
else y->right = z;
z->key = key;
z->size = 1;
z->left = z->right = &nil;
z->color = RED;
OS_RB_TREE_INSERT_FIXUP(root,z);
}
void OS_RB_TREE_TRANSPLATE(OS_RB_TREE **root,OS_RB_TREE *u,OS_RB_TREE *v)
{
if(u->parent == &nil)
*root = v;
else if(u == u->parent->left)
u->parent->left = v;
else u->parent->right = v;
v->parent = u->parent;
}
void OS_RB_TREE_DELETE_FIXUP(OS_RB_TREE **root,OS_RB_TREE *x)
{
while(x != *root && x->color == BLACK)
{
if(x == x->parent->left)
{
OS_RB_TREE *w = x->parent->right;
if(w->color == RED)
{
w->color = BLACK;
x->parent->color = RED;
LEFT_ROTATE(root,x->parent);
w = x->parent->right;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
x = x->parent;
}
else
{
if(w->right->color == BLACK)
{
w->left->color = BLACK;
w->color = RED;
RIGHT_ROTATE(root,w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
LEFT_ROTATE(root,x->parent);
x = *root;
}
}
else
{
OS_RB_TREE *w = x->parent->left;
if(w->color == RED)
{
w->color = BLACK;
x->parent->color = RED;
RIGHT_ROTATE(root,x->parent);
w = x->parent->left;
}
if(w->left->color == BLACK && w->right->color == BLACK)
{
w->color = RED;
x = x->parent;
}
else
{
if(w->left->color == BLACK)
{
w->right->color = BLACK;
w->color = RED;
LEFT_ROTATE(root,w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->left->color = BLACK;
RIGHT_ROTATE(root,x->parent);
x = *root;
}
}
}
x->color = BLACK;
}
void OS_RB_TREE_DELETE(OS_RB_TREE **root,OS_RB_TREE *z)
{
if(z == &nil)
return;
OS_RB_TREE *y = z;
COLOR y_original_color = y->color;
OS_RB_TREE *x;
if(z->left == &nil)
{
x = z->right;
OS_RB_TREE_TRANSPLATE(root,z,z->right);
OS_RB_TREE *parent = z->parent;
while(parent != &nil) //祖先结点的size都减1
{
parent->size -= 1;
parent = parent->parent;
}
}
else if(z->right == &nil)
{
x = z->left;
OS_RB_TREE_TRANSPLATE(root,z,z->left);
OS_RB_TREE *parent = z->parent;
while(parent != &nil)
{
parent->size -= 1;
parent = parent->parent;
}
}
else
{
y = MINIMUM(z->right);
y_original_color = y->color;
OS_RB_TREE *parent = y->parent;
while(parent != &nil)
{
parent->size -= 1;
parent = parent->parent;
}
x = y->right;
if(y->parent == z)
x->parent = y;
else
{
OS_RB_TREE_TRANSPLATE(root,y,y->right);
y->right = z->right;
y->right->parent = y;
}
OS_RB_TREE_TRANSPLATE(root,z,y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if(y_original_color == BLACK)
OS_RB_TREE_DELETE_FIXUP(root,x);
delete z;
}
OS_RB_TREE *SELECT(OS_RB_TREE *x,int i)
{
int r = x->left->size + 1;
if(i == r)
return x;
else if(i < r)
return SELECT(x->left,i);
else return SELECT(x->right,i-r);
}
int OS_RANK(OS_RB_TREE *root,int key)
{
if(key == root->key)
return root->left->size + 1;
else if(key < root->key)
return OS_RANK(root->left,key);
else return OS_RANK(root->right,key) + root->left->size + 1;
}
int main()
{
int n,m;
cout << "Input n and m: ";
cin >> n >> m;
cout << endl;
OS_RB_TREE *root = &nil;
for(int i = 1; i <= n; ++i) //创建红黑树
OS_RB_TREE_INSERT(&root,i);
int j = m, k = n;
while(k >= 2)
{
OS_RB_TREE *x = SELECT(root,j);
cout << x->key << ' ';
OS_RB_TREE_DELETE(&root,x);
--k;
j = (j + m - 2) % k + 1; //不用(j + m - 1) % k是因为这样计算可能使j=0,实际上j不为0
}
OS_RB_TREE *x = SELECT(root,1);
cout << x->key << endl;
OS_RB_TREE_DELETE(&root,x);
return 0;
}