数据结构约瑟夫环(C++实现)【顺序结构及循环链表结构】

问题:编号为1、2、···、n的n个人按顺时针方向围坐一圈,每人有一个正整数编号。从某个位置上的人开始报数,数到m的人便出列;下一个人(第m+1个)又从1数起,数到m的人便是第2个出列的人;依次重复下去,直到最后一个人出列,于是得到一个新的次序,试设计程序求出出列顺序。

顺序结构

要点:

1.利用动态数组(末尾释放)及函数移位

2.及时判断是否到末尾,回到开头

#include<iostream>
using namespace std;

void Delete(int a[],int i,int n)
{
      for(int j=i;j<n;j++)
		 a[j]=a[j+1]; 
}
     

int main()
{
        int m,n,l;
		cin>>m>>n;
		int *a=new int[n];
		l=n;
        for (int i = 0; i <l ; i++) 
        {  
			a[i]=i+1;  
        }  
		
        //从第K个开始报数  
        int k = 0;  
        while (l >0) {  
            k = k + m;  
            //报m的人的当前索引位置  
            k = k % l - 1;  
           // 判断是否到队尾  
            if (k < 0) {  
                cout<<a[l-1];   
                k = 0;
			    l--;
            } else {  
                cout<<a[k];
                Delete(a,k,l); 
                l--;
            }  
        }  
      
    delete[] a;
	cout<<endl;
	return 0;
}

单向循环链表结构

要点:

1.建立单向链表,然后将尾指针指向头结点,得到单向循环链表。

2.每数到m出列一个人并删去他。

#include<iostream>
 
using namespace std;
 
typedef struct CLinkList
{
    int data;
    struct CLinkList *next;
}node;
 
 
int main()
{
//建立循环链表
    node *L,*r,*s;
    L = new node;
    r =L;
	int n,m;
	cin>>m;
    cin>>n;
    int k = m;
    for(int i = 1;i<=n;i++)       //尾插法建立链表
    {
        s = new node;
        s->data = i;
        r->next = s;
        r= s;
    }
    r->next =L->next;       //让最后一个结点指向第一个有数据结点
    node *p;
    p = L->next;
    delete L;   //删除第一个空的结点
 
///模拟解决约瑟夫问题
    while(p->next != p)                            
    {
        for(i = 1;i<k-1;i++)
        {
            p = p->next;                        
        }
       
        cout<<p->next->data;
        p->next = p->next->next;                   //将该节点从链表上删除。
        p = p->next;
    }
    cout<<p->data<<endl;
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值