CLRS第十四章思考题

思考题14-1

a) 设最大重叠点不是重叠区间的任意一个区间的端点。令 p 是最大重叠区间为 m 段区间的一个点,但不是重叠区间的任何一个区间的端点。又设 p 是和 m 段区间重叠的一个端点(一定有这样一个点,否则交叉不会在此终结) ,显然 p p 具有相同的重叠区间(都为 m),且是一个端点,和假设矛盾;

b) 按照树中的建议,使用红黑树,并且关联左右端点。
e1,e2,...,en 表示所有区间端点经过排序后的序列,令 s(i,j)=p(ei)+p(ei+1)+...+p(ej),1ijn ,我们希望找到一个 i 使 s(1,i)最大。
对树中的结点 x ,令 l(x),r(x) 分别表示排序后以 x 为根的最左和最右端点下标,则以 x 为根的子树包含的端点是 el(x),el(x)+1,...,er(x) 。对每个结点添加三个属性。 x.v 表示以 x 为根的所有端点的 p 值之和。 x.m 表示对 i {l(x),l(x)+1,...,r(x)} 中的所求的 s(l(x),i) 的最大值。最后 x.o 表示以 x 为根的所有结点中的最大覆盖点。对哨兵来说,T.nil.m=T.nil.v=0
现在有以下计算公式:

x.v=x.left.v+p(x)+x.right.v

x.m=maxx.left.mx.left.v+p(x)x.left.v+p(x)+x.right.mxxx

对于 INTERVAL-INSERT,我们插入区间的两个端点;
对于 FIND-POM,我们返回 T.root.o
因为我们对所有的端点都插入到一颗红黑树中,然后用来求解 T.root.o ,所以不用删除树中的任何结点。
由定理14.1知时间复杂度为 O(lgn) ,实际上 FIND-POM只需 O(1) 时间。

思考题14-2

a) 建立一个循环链表,链表中每个结点包括关键字和下一个结点信息,建表时间是 O(n) ,然后从头开始,每计数到 m 时删掉链表中的一个元素,总时间是 O(mn)=O(n)

b) 直接使用第14.1节中的顺序统计树,假设现在还剩 k 个人,然后要被移除的是在剩余的人中排名第 j 的那个,那么我们删除第 j ,然后将 k 减一表示还剩 k1 个人,接着找到第 (j+m1)modk 的那个人那里(这里减一是因为我们刚刚删除了一个人)。

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值