您的位置:首页 > 其它

循环链表--解决Josephus问题

2012-04-06 16:54 441 查看
单向循环链表:

空表:L->next = L。

与单链表的联系:判断表尾的方法不同:单链表用p==NULL;循环链表用p==L。

双向循环链表:一个结点包含指向后继(next) 和指向前驱(prior) 两个指针,两个方向又分别构成循环链表。

双向循环链表的插入和删除:

1.p之后插入s

s->next = p->next;

p->next = s;

s->prior = p;

s->next->prior = s;

2.p之前插入s

s->prior= p->prior;

p->prior = s;

s->next = p;

s->prior->next = s;

3.删除p之后继s

s = p->next;

p->next = s->next;

p->next->prior = p;

4.删除p

p->prior->next= p->next;

p->next->prior= p->prior;

循环链表--解决Josephus问题

题目:n个人围成一圈,从第一个开始顺序报数1,2,3.凡是报到3 者退出圈子,最后剩下的就是胜利者

用循环链表解决:

#include <iostream>
using namespace std;

typedef struct Node
{
int data;
struct Node *next;
}Node,*List;

List Creatlist(int n)
{
List head,p;
int i;
head=(Node*)malloc(sizeof(Node));
if(!head)
{
cout<<"memory allocation error!\n";
exit(1);
}
head->data=1; head->next=head;
for(i=n;i>1;--i)
{
p=(Node*)malloc(sizeof(Node));
if(!p)
{
cout<<"memory allocation error!\n";
exit(1);
}
p->data=i; p->next=head->next; head->next=p;
}
return head;
}

void Output(List head)
{
List p=head;
do
{
cout<<p->data<<" ";
p=p->next;
}while(p!=head);
cout<<endl;
}

void Play(List head,int n,int m) //第一种方法
{
List p,q;
int c,k;
p=head; c=1; k=n;
while(k>1)
{
if(c==m-1)
{
q=p->next; p->next=q->next;
cout<<q->data<<" ";
free(q);
c=0; --k;
}
else {c++; p=p->next;}
}
cout<<"The winner is "<<p->data;
cout<<endl;
}

void Josephus(List h,int n,int m)//第二种方法
{
Node* p=h,*pre=NULL;
int i,j;
for(i=0;i<n-1;++i)
{
for(j=1;j<m;++j)
{
pre=p;
p=p->next;
}
cout<<"出列的人是 "<<p->data<<endl;
pre->next=p->next; free(p);
p=pre->next;
}
cout<<"The winner is "<<p->data<<endl;
}

int main()
{
List head;
int n,m;
cout<<"Input the n and m :";
cin>>n>>m;
head=Creatlist(n);
Output(head);
Josephus(head,n,m);

return 0;
}


执行结果:

Input the n and m :10 3

1 2 3 4 5 6 7 8 9 10

出列的人是 3

出列的人是 6

出列的人是 9

出列的人是 2

出列的人是 7

出列的人是 1

出列的人是 8

出列的人是 5

出列的人是 10

The winner is 4

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