2014-10-10 约瑟夫环+循环列表

来源:互联网 发布:linux文件拷贝命令 编辑:程序博客网 时间:2024/06/12 11:54
约瑟夫问题.cpp : 定义控制台应用程序的入口点。
约瑟夫问题:已知n个人(n>=1)围坐一圆桌周围,从1开始顺序编号。从序号为k(k由用户指定)
的人开始报数,顺时针数到m(m由用户指定)的那个人出列。他的下一个人又从1开始报数,数到

m的那个人又出列。依此规则重复下去,直到所有人全部出列。请问最后一个出列的人的编号。




#include "stdafx.h"
#include "malloc.h"
typedef struct Node 
{
int data;
struct Node *next;
}LNode,*LinkList; 


LinkList Creat_LinkList(int n)  //在表尾插入,建立循环链表,n表示链表长度

LinkList s,q,H;
for (int i=1;i<=n;i++)
{
s=(LNode *)malloc(sizeof(LNode)); 
s->data=i;
s->next=NULL;
if (i==1)
{
H=s;
q=s;
}
else
{
q->next=s;
q=q->next;
}
}
q->next=H;
if (H!=NULL)
return H;
else
{
printf("error");
return NULL;
}  
}


int GetLength(LinkList L)//计算当前约瑟夫环上的人数
{
if (L==NULL)
{
printf("指针出错了\n");
return -1;
}
else
{
int i=1;
LinkList p=L->next;
while(p!=L)
{
i++;
p=p->next;
}
return i;
}
}


LinkList Del(LinkList *L,int i)//返回当前出列的人,q指向当前应该出列的人,作为函数的返回值
{
if (i==1)
i+=GetLength(*L);
LinkList q,p=*L;
int j=0;
while (j<i-2)
{
p=p->next;
j++;
}
q=p->next;
p->next=p->next->next;
*L=p->next;//改变循环链表的头指针,本轮出列之后从下一个开始
return q;
}


void Joseph(LinkList L,int n,int m)//n表示总人数,m表示每次报数的人数
{
int k;
printf("请输入第一个报数的人:");
scanf("%d",&k);
if (k<1 || k>n)
{
printf("请输入1--%d之间的数\n",n);
return;
}
else
{
printf("出列的顺序:\n");
for (int i=1;i<n;i++)
{
LinkList q;
q=(LNode *)malloc(sizeof(LNode));
if (i==1)
{
q=Del(&L,k+m-1);
}
else
{
q=Del(&L,m);
}
printf("第%d次出列的号数:%d\n",i,q->data);
free(q);
}
printf("最后一个出列的号数是:%d\n",L->data);
}
}


0 0
原创粉丝点击