這是一個經典的問題,內容是click here。本文章要實現的是:一共n個人,從第k個人開始報數,數到m的淘汰。從他的下一個人接着數,直到剩餘一個人爲止。
首先,生成n個人的單鏈表,並從第k個人開始生成。
首尾相接後,如圖:
第一個節點數據元素存的是k,也就是說從第1個開始數到m,
此時q指向m-1,p指向第m個元素。將第p個元素刪除即可,然後循環遍歷,知道最後一個人剩下。
思路就是這樣。
編譯環境爲Code::Blocks,由於能力有限,難免有bug,僅給讀者提供思路。
代碼如下:
#include<stdio.h>
#include<string.h>
typedef int ElemType;
typedef struct node
{
ElemType data;
struct node *next;
}LNode;
void Josephus(int n,int m,int k)
{
LNode *q,*p;
int i;
p=(LNode *)malloc(sizeof(LNode));//申請一個新節點
q=p;
for(i=1;i<n;i++) //for循環吧n-1個人排上號
{
q->data=k; //第一個節點爲k,即從k開始
k=k%n+1; //避免k=n的情況
q->next=(LNode *)malloc(sizeof(LNode));
q=q->next; //q一直指向最新的節點
}
q->data=k; //q指向第n個人,k也是第n個數
q->next=p; //尾指針指向頭結點,形成循環單鏈表
printf("依次淘汰的人\n");
while(p->next!=p) //判斷是否剩餘一個人
{
for(i=1;i<m;i++)
{
q=p; //當從循環出來q在m-1處
p=p->next; //當從循環出來的時候,p節點在m位置處
}
q->next=p->next;//q指向m+1的節點,即淘汰第m個人
printf("%4d",p->data);
free(p);
p=q->next;
}
printf("\n剩的最後一人\n");
printf("%4d",p->data);
}
int main()
{
int n,m,k;
printf("輸入人數n,總報數m,開始號k\n");
scanf("%d%d%d",&n,&m,&k);
Josephus(n,m,k);
return 0;
}
運行後結果: