约瑟夫(Jonsephus)问题(C++)

约瑟夫(Jonsephus)问题描述

 n个人围成一个环,从第i个开始,由1至interval不断报数,凡报到interval的出列,直到环空为止。

      例如:总共有8个人围成一个环,取间隔未3。假设从第1个人开始报数,当有人报的3的时候,这个人出列。从下个人再次进行报数,依次类推,当剩下最后一人时直接出列。

      输入1 2 3 4 5 6 7 8  ,取间隔为3,则输出序列为3 6 1 5 2 8 4 7。

 对数据进行操作:

 首先确定从那个位置开始报数

while(表结点数>1)
{
  for(1 到间隔数)
   {
    记录节点数目;
    输出并删除该结点;
   }
}
输出并删除最后一个结点;
#include <iostream>
#include <iomanip>
using namespace std ;
 struct Jonse
  { int code ; 
    Jonse *next; 
  };
Jonse * CreateList( int );

void PrintList(Jonse *);

void Out(Jonse *, int, int ) ;

int main()
{ 
   Jonse * head ;  
   int num , interva , begin ;
   cout << "\n请输入数字总数:\n" ;
   cin >> num ;  
   head = CreateList(num) ; //创建链表 
   PrintList(head) ; //打印链表信息 
   cout << "\n输入计数位置:\n" ;  
   cin >> begin ; 
   cout << "\n输入打印间隔:\n" ;  
   cin >>  interva ;  
   cout << "输出序列:\n" ;  
   Out( head, begin, interva ) ;  
}
Jonse * CreateList ( int n )//创建N个结点的单项循环链表 ,头插法 
  { 
    Jonse *head, *p ; // 声明局部变量的链表指针 
    head= new Jonse ; 
    p = head; 
    for ( int i=1;i<=n;i++)
    { 
	  p->code = i ;  
      if (i<n)
	  { 
	    p->next =new Jonse; //使用P指针来建立后续结点 
	    p = p->next; 
	  }
    }
    p->next = head; //构成循环链表 
    return head;  //返回头指针 
}
void PrintList(Jonse *head) 
{  
   Jonse *p;   
   p=head;  
    do{ 
     	cout << p->code << '\t' ;   
    	p = p->next ; 
      } while(p!=head) ;  

}
void Out(Jonse *head, int i, int d)
{ 
  Jonse *p,*q ;   
  int k ;  
  p = head; 
  for( q = head ;q->next != head;q=q->next) ; //建立双跟踪指针,寻找P的前置 
  for( k = 1; k<i; k++) //寻找开始位置 
   { 
     q=p;  
	 p=p->next;  
   }
  while(p!= p->next)//当剩下最后一个结点的时候跳出循环 
  { 
    for (k=1;k<d;k++) //计数,输出间隔位置的结点值 
	 { 
	   q = p ;  
	   p=p->next ; 
     }
    cout<<p->code<< '\t' ; 
    q->next = p->next ;//删除结点 
    delete p ;//释放空间 
    p = q->next ;//移动指针 
  }
    cout << p->code << endl ;//输出并删除最后一个结点 
    delete p ;
}

参考书籍《C++ 程序设计基础》周霭如。[^2]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值