n个数据元素构成一个环,从环中任意位置开始计数,计到m将该元素从表中取出,重复上述过程,直至表中只剩下一个元素。
思路
用一个无头结点的循环单链表来实现n个元素的存储。
循环单链表:尾指针指向头结点。这样指针可以循环移动。
技巧
1,开两个指针,一个指向需要操作的元素的指针q,另一个指向需要操作的元素的前一个元素的指针p。为什么要指针q?当需要删除q所指的元素时,需要知道q之前的元素的位置,因为要修该p所指元素的指针域。
2,循环链表某结点的指针指向本身,则该链表就只有该结点。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#define NULL 0
typedef struct LNode
{
int num;
struct LNode *next;
} LNode, *Linklist;
Linklist head,tail;
void Createlist(int n)
{
int i;
Linklist p,q;
head=(Linklist)malloc(sizeof(LNode));
q=head;
q->num=1;
for(i=2; i<=n; i++)
{
p=(Linklist)malloc(sizeof(LNode));
p->num=i;
q->next=p;
q=p;
}
p->next=head;
tail=p;
}
void Outlist(int k)
{
int i;
Linklist p,q;
q = head;
p = tail;
for(i=1;i<k;i++)
{
p = p->next;
q = q->next;
}
while(q != p)
{
printf("%3d",q->num);
p->next = q->next;
q = p->next;
for(i=1;i<k;i++)
{
p = p->next;
q = q->next;
}
}
printf("%3d\n",q->num);
}
int main()
{
int k,n;
printf("---------------约瑟夫环问题--------------\n");
printf("\n请输入总人数和从第几个人开始报数n,k:\n");
scanf("%d%d",&n,&k);
Createlist(n);
printf("\n出队的次序:\n");
Outlist(k);
return 0;
}