描述
设有N名同学手拉手围成一圈,自1、2、3、......开始编号,现从1号开始连续数数,
每数到M将此同学从圈中拉走, 求最后被拉走的同学的编号
每数到M将此同学从圈中拉走, 求最后被拉走的同学的编号
输入
两个正整数,分别为N和M。0<N<=100 ;0<M<65535
输出
一个正整数,为最后被拉走的同学的编号,最后输出回车
输入样例
5 3
输出样例
4
1.单循环链表实现
#include<stdio.h>
#include<stdlib.h>
typedef struct node
{
int data;
struct node *next;
}LinkNode,*LinkList;
LinkList Create(int n)
{
LinkNode *p,*q;
int i;
q = (LinkNode *)malloc(sizeof(LinkNode));
p = q;
q->data = 1;
q->next = q;
for(i = 2;i <= n;i++)
{
p = (p->next = (LinkNode *)malloc(sizeof(LinkNode)));
p->data = i;
p->next = q;
}
return p;
}
void Josephus(LinkList head,int m)
{
while(head != head->next)
{
for(int i = 1;i < m;i++)
{
head = head->next;
}
head->next = head->next->next;
}
printf("%d\n",head->data);
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
LinkList head;
head = Create(n);
Josephus(head,m);
return 0;
}
2.双向循环链表实现
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct node
{
int data;
struct node *next;
struct node *prior;
}DoubleNode,*DoubleList;
DoubleList Create(int n)
{
DoubleList head = NULL;
DoubleNode *p,*q;
int i;
for(i = 1;i <= n;i++)
{
p = (DoubleNode *)malloc(sizeof(DoubleNode));
if(p == NULL)
{
printf("动态内存分配失败!\n");
exit(-1);
}
p->data = i;
p->next = NULL;
if(head == NULL)
{
head = p;
p->prior = head;
p->next = head;
}
else
{
p->next = q->next;
q->next = p;
p->prior = q;
head->prior = p;
}
q = p;
}
return head;
}
void Josephus(DoubleList head,int n,int m)
{
int i;
DoubleNode *p,*q;
p = head;
while(p->next != p)
{
for(i = 1;i < m;i++)
{
q = p;
p = p->next;
}
q->next = p->next;
p->next->prior = q;
printf("%d ",p->data);
free(p);
p = q->next;
}
printf("%d\n",p->data);
free(p);
return;
}
int main()
{
DoubleList Head;
int n, k, m;
//printf("输入玩家个数 n = ");
scanf("%d", &n);
//printf("报数为 m 的人出列 m = ");
scanf("%d", &m);
Head = Create(n);
Josephus(Head, n, m);
return 0;
}
我个人觉得单循环链表更好用些~