Josephus问题:设有n个人围坐在一个圆桌周围,现从第s个人开始报数,数到第m的人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列。如此反复直到所有的人全部出列为止。
思路:构建一个没有头结点的循环链表,实现自己的删除函数,数到第几个结点就把这个结点从链表中删除,然后重新数。
难点在于写删除函数。
代码如下:
#include <stdio.h> #include <stdlib.h> typedef struct student * PNode; typedef struct student{ int data; PNode next; }Node; PNode create(int n) { PNode head=(PNode)malloc(sizeof(Node)); PNode p; int data=0; p=head; printf("请输入结点的值\n"); scanf("%d",&data); p->data=data; while(--n) { p->next=(PNode)malloc(sizeof(Node)); p=p->next; printf("请继续输入结点的值\n"); scanf("%d",&data); p->data=data; } p->next=head; return head; } void print(PNode link) { PNode head,p; if(link==NULL) return; head=link; p=link; while(p->next!=head) { printf("%d ",p->data); p=p->next; } printf("%d\n",p->data); } PNode del(PNode link,int num) { PNode head=link; PNode p=link; PNode temp; if(link==NULL) { // printf("链表为空"); return NULL; } // printf("要删除结点的值为%d\n",num); //删除头结点 if(p->data==num) { if(p->next==head) //只剩下一个结点的情况 { // printf("链表删除完毕。\n"); free(link); return NULL; } while(p->next!=head) p=p->next; temp=p->next; p->next=p->next->next; head=p->next; free(temp); return head; } //删除非头结点 while(p->next->data!=num && p->next!=head) { p=p->next; } if(p->next==head) { // printf("没有找到这样的结点。\n"); return head; } temp=p->next; p->next=p->next->next; free(temp); return head; } void Josepus(PNode link,int n,int k,int m) { if(link==NULL) { printf("链表为空\n"); return; } printf("打印出列的顺序:"); PNode p=link; int r=k+m-2; //r为链表要移动的次数,根据图示来进行r大小的确认 while(r--) { p=p->next; } printf("%d ",p->data); p=del(p,p->data); while(p!=NULL) { r=m-1; while(r--) { p=p->next; } printf("%d ",p->data); p=del(p,p->data); } printf("\n"); } int main(void) { int n,num; int s,m; printf("请输入要创建多少个结点\n"); scanf("%d",&n); PNode link=create(n); printf("打印初始链表\n"); print(link); printf("请输入要从第几个人开始报数\n"); scanf("%d",&s); printf("请输入要报多少个人\n"); scanf("%d",&m); Josepus(link,n,s,m);/* 测试删除函数用地 while(1) { printf("请输入要删除的结点的值\n"); scanf("%d",&num); link=del(link,num); if(link==NULL) break; printf("打印删除后的链表\n"); print(link); } */ return 0; }
时间: 2024-10-28 11:02:28