Josephus问题解决方法三(单向循环链表标识法)

前面解决Josephus问题时( http://blog.itpub.net/29876893/viewspace-1815055/ http://blog.itpub.net/29876893/viewspace-1850077/ ) ,都是找到该同学后,把该同学从环中除去,然后剩下的同学再组成一个新的环,终止条件是p != p->next。下面我们换种方式考虑该问题,可不可以找到该同学后,标识该同学,然后一直循环该环,直到把所有的人都标识,终止循环的条件是标识位等于环中的人数(flag=length),最后"标识"的同学就是获胜者。我把这种方法叫做,“单向循环链表标识法”,下面给出代码:

点击(此处)折叠或打开

  1. #include<iostream>
  2. using namespace std;
  3. typedef struct Note{
  4.     char ch;
  5.     struct Note *next;
  6. }*node;

  7. int length;
  8. int flag;

  9. void initNote(node first) {
  10.     first = new Note;
  11.     first->next = NULL;
  12. }

  13. void createNote(node first) {
  14.     node p, q;
  15.     p = first;
  16.     cout << "请依次输入学生的编号:" << endl;
  17.     for (char ch; cin >> ch, ch !='#';) {
  18.         q = new Note;
  19.         p->next = q;
  20.         q->ch = ch;
  21.         cout << q->ch << " ";
  22.         p = q;
  23.         length++;
  24.     }
  25.      p->next=first->next;
  26. }
  27. void searchNote(node first,int n) {
  28.   
  29.     cout << "出队的顺序依次是:" << endl;
  30.     while (true) {                   //死循环,为了找出所有标识结点
  31.         for (int i = 1; i <=n; i++) {
  32.                 
  33.                 first = first->next;
  34.                 if (first->ch == NULL){ //只要循环到ch为空的结点,i减1,并且继续执行for循环
  35.                     i--;
  36.                     continue;
  37.                 }
  38.         }
  39.             flag++;    //只要结点的first->ch=NULL,则标识就增加1
  40.             cout << first->ch << " ";
  41.             if (flag == length) {  //已经找到了所有的标识结点,退出死循环
  42.                 break;
  43.             }
  44.             first->ch = NULL;//把标识结点的数据域置为空
  45.     }
  46.     cout << endl;
  47.     cout << "获胜的同学是:" << endl;
  48.     cout << first->ch;    //打印出获胜者
  49. }
  50. void deleteNote(node q) {
  51.     node p = q;
  52.     for (; p != q; p = p->next) {
  53.         node no = p;
  54.         delete no;
  55.     }
  56.     cout << "环已销毁!!!" << endl;
  57. }
  58. int main() {
  59.     Note note;
  60.     initNote(&note);
  61.     createNote(&note);
  62.     cout << endl;
  63.     searchNote(&note,4);
  64.     cout << endl;
  65.     deleteNote(&note);
  66. }
运行结果:

形成环这里不必多说,关键在于 void searchNote ( node first , int  n ),思路就是找到同学后,把该同学贴上标签,然后继续循环该环,当找到已经被贴上标签的同学,就跳过该同学,当找到所有的同学后,那么剩下的同学就是获胜 者,当然别忘了,游戏结束后,不能让同学还是手拉手围成一个环,那就是 void deleteNote ( node q )的功能啦,把该环"销毁"了。上面的解题思路,我想很多朋友会想到,可不可以用数组解决该问题,当然可以啦!关键是清晰的画出程序流程图解,程序写起来会变的相对容易些。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29876893/viewspace-1851818/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29876893/viewspace-1851818/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值