• 算法导论142习题解答 Josephus排列(约瑟夫环)


    CLRS 14-2 Josephus问题的定义如下:假设n个人排成环形,且有以正整数m<=n。从某个制定的人开始,沿环报数,每遇到第m个人就让其出列,且报数进行下去。这个过程一直进行到所有人都出列为止。每个人出列的次序定义了整数1,2,...,n的(n, m)-Josephus排列。例如,(7,3)-Josephus排列为<3,6,2,7,5,1,4>。
    a)假设m为整数。请描述一个O(n)时间的算法,使之对给定的整数n,输出(n, m)-Josephus排列。
    b)假设m不是个常数。请描述一个O(nlgn)时间的算法,使给定的整数n和m,输出(n, m)-Josephus排列。

    解答:
    a)首先,我们很容易想到用一个循环链表,即最后一个结点指向头结点的单链表。然后,选定一个结点,走m步,输出此结点的值,然后删除之,然后再走m步,依次循环下去,由于建立链表时间为O(n),而删除的过程为O(m*n),由于m为常数,故总的时间复杂度为O(n)。
    (伪)伪代码:

    //i为起始点
    1
    PROCESS(list, i) 2 { 3 node = list.get(i); 4 while (list != NULL) 5 { 6 for (i = 0; i < m-1; i++) 7 { 8 node = node->link; 9 } 10 tmp = node;//保存node的副本 11 print node->key;//输出值 12 node = node->link;//在删除之前指向下一个结点 13 delete tmp;//从链表删除,当然,之前还有指针之间的链接转变 14 } 15 }


    b)第二问,由于在这一章,所以会采用基于红黑树的顺序统计树。
    这里可以结合着伪代码和下面的例子看整个流程是怎么走的。
    (伪)伪代码:

     1 //建立顺序统计树,在题设中,原始数据是一个排好序的数组,即{1,2,3...n}
     2 CreateTree()
     3 {
     4   for (i = 1; i <= n; i++)
     5     insert(T, node[i]);//node存储的是数组元素
     6 }
     7 
     8 //T为顺序统计树,i为选择的起始点,这里的i表示的是位置,不是node里面的key值,可以理解为第i小的数
     9 Process(T, i)
    10 {
    11   while (T != NULL)
    12   {
    13     i = (i+m-2)%(n--) + 1;//在这里,我们不用(i+m-1)%(n--),是因为这个表达式可能计算的结果等于0,但i != 0;
    14     print key[OS-SELECT(T, i)];
    15     OS-DELETE(T, i);
    16   }
    17 }

    我们来对数组{1,2,3,4,5,6,7}走一遍,我们选择第一个数为起始点,i=1,选择m=3,则
    i = (i+m-2)%(n--) + 1 = 3,好的,输出第3个数,即3,然后去除3,剩下{1,2,4,5,6,7},n=6接着
    i = (i+m-2)%(n--) + 1 = 5,好的,输出第5个数(这里不是5,在树中剩下的元素中,是第五小的数),即为6,然后删除6,现在剩下元素为{1,2,4,5,7},n=5,接着
    i = (i+m-2)%(n--) + 1 = 2,好的,输出第2个数,即为2,然后删除2,现在剩下元素为{1,4,5,7},n=4,接着
    i = (i+m-2)%(n--) + 1 = 4,输出第四个数,即为7,然后删除7,现在剩下元素为{1,4,5},n=3,接着
    ......
    我们发现,这个算法的执行是正确的。

  • 相关阅读:
    【调侃】IOC前世今生
    经典 makefile 教程
    Win7  CMD大全
    关于验证码识别3
    关于验证码识别2
    关于验证码识别 1
    DirectUI的初步分析-转
    winform软件版本检测自动升级开发流程(转)
    如何让在panel里的子窗体随panel的大小改变而变化?(转)
    C#如何控制panel加载的字窗体中控件的位置随着显示器分辨率大小而改变
  • 原文地址:https://www.cnblogs.com/null00/p/2494241.html
Copyright © 2020-2023  润新知