C語言利用迴圈單鏈表解決約瑟夫問題
阿新 • • 發佈:2018-12-12
Description
編號是1,2,……,n的n個人按照順時針方向圍坐一圈,每個人持有一個密碼(正整數)。一開始任選一個正整數作為報數上限值m,從第一個仍開始順時針方向自1開始順序報數,報到m時停止報數。報m的人出列,將他的密碼作為新的m值,從他的順時針方向的下一個人開始重新從1報數,如此下去,直到所有人全部出列為止。請設計一個程式輸出出列順序。
提示:儲存結構採用不帶頭結點的迴圈單鏈表,結點結構如下:
typedef struct Node
{ int ID;
int password;
struct Node *next;
}LNode,*LinkList;
要求:
(1)編寫建立迴圈單鏈表的函式,依次輸入每個人的ID和password建立不帶頭結點的迴圈單鏈表。
(2)編寫函式,按照規則依次刪除相應的元素。
(3)main()函式呼叫(1)和(2)中的函式,輸出約瑟夫序列。
注意:m=1 時需要特殊處理。
Input
輸入n
輸入m
第1行為n
第2行為m
接下來每行表示每個人的ID和password
Output
依次輸出出列者的ID
每輸出一個人的ID換行。
Sample Input
8 4 1 3 2 1 3 9 4 2 5 4 6 7 7 4 8 6
Sample Output
4 6 7 3 5 8 2 1
HINT
注意:處理m=1的特殊情況。
輸出最後一個人的ID後,也要換行。
/*約瑟夫環*/ #include <stdio.h> #include <stdlib.h> typedef struct LNode{ //定義迴圈連結串列 int id; int password; struct LNode * next; }LNode,*LinkList; LinkList CreatList(LinkList head,int n) { int i; LinkList p,q; head = (LinkList)malloc(sizeof(LNode)); q = head; scanf("%d %d",&q->id,&q->password); for(i = 2;i<=n;i++) { p = (LinkList)malloc(sizeof(LNode)); scanf("%d %d",&p->id,&p->password); q->next = p; q = p; } p->next =head; return head; } /* void Display(LNode *pHeader) { LNode *pCurNode; pCurNode=pHeader; printf("%d ",pCurNode->password); while(pCurNode->next!=pHeader) { pCurNode = pCurNode->next; printf("%d ",pCurNode->password); } }*/ void Joseph(LinkList head,int k) { LinkList p,q; int m,i; p = head; m =k; /* for(i = 1;i<k;i++) { p = p->next; }*/ // q = p; while(p->next!=p) { for(i=1;i<m;i++) { q=p; p = p->next; } m = p->password; printf("%d\n",p->id); q->next = p->next; free(p); p = q->next; } printf("%d\n",p->id); free(p); } int main() { int k,n; LinkList L,head; L = NULL; scanf("%d",&n); scanf("%d",&k); head = CreatList(L,n); //Display(head); Joseph(head,k); return 0; }