您的位置:首页 > 编程语言

约瑟夫问题总结及代码实现

2013-09-03 19:50 375 查看
约瑟夫问题,具体含义通过百度百科/维基百科查阅,分别用数组和链表两种方式实现

注:一下用C++实现,但本质和C一样,只需要在输出、入把cout,cin改成printf,scanf即可

1、用数组实现

主要原理是假设n为总人数,m为间隔,s为起始报数位置,则s = (s+m-1)%n就是第一个出局的人,那么只要把这个人移到最后,s之后的往前移动,n--即可

void Juseph1(int n, int m, int s)
{
int *a = new int
;//保存n个人的编号(1-n)

//C语言用a = malloc(sizeof(int)*n)
int i;
int j;
int s1 = s;
int temp;

for(i=0; i<n; i++)
a[i] = i + 1;//a[i]存i+1的编号
for(i=n; i>1; i--)
{
s1 = (s1 + m -1) % i;//s1便是每次循环第一个出局的人
if(s1 == 0)//若循环中最后一人出局就不用往前移了
s1 = i;
temp = a[s1-1];
for(j=s1; j<i; j++)
{
a[j-1] = a[j];
}
a[i-1] = temp;
}

for(i=n; i>0; i--)
{
cout << a[i-1] << " ";

//C语言用printf("%d ", a[i-1])
}
cout << endl;

//C语言用printf("\n" )

delete []a;

//C语言用free(a)
}

2、用链表实现

用单向循环链表实现,n表示总人数,出局一个减一个,直到为1

typedef struct List

{

int data;

struct List *next;

}List;

List *CreatList(int n)

{

List *p = NULL;

List *head = NULL;

List *tail = NULL;

while(n--)

{

p = new List;

cout<<"please input the data of nodes!"<<endl;

cin>>p->data;

p->next = NULL;

if(head == NULL)

{

head = p;

tail = head;

}

else

{

tail->next = p;

tail = p;

}

}

tail->next = head;

return head;

}

void Display(List *head)

{

List *p = head;

while(p->next != head)

{

cout<<p->data<<" ";

p = p->next;

}

cout<<p->data<<endl;

}

void Juseph(List *head, int n,int m, int s)//n个总个数,m为间隔,s为起始位置

{

List *p = head;

List *q = NULL;

List *temp = NULL;

int i = 0;

int j = 0;

while(p->next != head)

{
j++;

if(j == s)

break;

p = p->next;

}

while(n)

{

i++;

if(i == m)

{

cout<<p->data<<" ";

i = 0;

n--;

temp = p->next;

delete p;

q->next = temp;

p = temp;

}

else

{

q = p;

p = p->next;

}

}

cout<<endl;

head = NULL;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: