描述
设有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; }
我个人觉得单循环链表更好用些~