1.3迴圈單鏈表之約瑟夫問題
阿新 • • 發佈:2020-12-14
1.3迴圈單鏈表之約瑟夫問題
迴圈單鏈表
1、與單鏈表類似,迴圈單鏈表也有帶頭和不帶頭。迴圈單鏈表不為空時,尾結點指標域為頭結點。為空時,頭指標的指標域指向它本身。
2、帶頭結點的迴圈單鏈表為空的判斷條件是head->next==head;
3、有時為了操作方便,迴圈單鏈表中只設尾指標。
約瑟夫問題:
有n個人,編號為1----n,圍成一個圓圈,順時針轉,從第k個人開始報數1,然後報到m的人出列,他的下一個人開始繼續從1報數,重複,直到所有人出列。要求n m k自己輸入。
程式碼實現:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define ListSize 100 typedef int DataType; typedef struct Node { DataType data; struct Node* next; }ListNode,*LinkList; LinkList CreateCycList(int n); //建立一個長度為n的迴圈單鏈表 void Josephus(LinkList head,int n,int m,int k); //在長度為n的迴圈單鏈表中,找出編號為m的出列 int DisplayCycList(LinkList head); //輸出迴圈單鏈表 void main() { LinkList h; int n, k, m; printf("輸入環中個數:"); scanf_s("%d",&n); printf("輸入開始報數序號:"); scanf_s("%d", &k); printf("報數為m的人出列,m為:"); scanf_s("%d", &m); h = CreateCycList(n); Josephus(h, n, m, k); } LinkList CreateCycList(int n) { LinkList head = NULL; ListNode* p,*q=NULL; for (int i = 1; i <= n; i++) { p = (ListNode*)malloc(sizeof(ListNode)); //在記憶體中劃分空間 p->data = i; //將i賦值給p的資料域 p->next = NULL; //將p的地址域置空 if (head==NULL) //如果迴圈單鏈表為空,則將剛分的空間p當做第一個結點 { head = p; } else //如果迴圈單鏈中已經有結點,則將p賦值給q的地址域,-----q是p的前一個結點 q->next = p; q = p; //然後把p賦值給q } q->next = head; return head; } void Josephus(LinkList head, int n, int m, int k) //在長度為n的迴圈單鏈表中,找出編號為m的出列 { ListNode* p, * q=NULL; p = head; for (int i = 1; i < n; i++) { q = p; p = p->next; } while (p->next!=p) { for (int i=1;i<=m;i++) { q = p; p = p->next; } q->next = p->next; printf("%4d\n",p->data); free(p); p = q->next; } printf("%4d\n",p->data); } int DisplayCycList(LinkList head) //輸出迴圈單鏈表 { ListNode *p=head; if (head=NULL) { printf("連結串列為空表\n"); return 0; } while (p->next!=head) { printf("%4d",p->data); p = p->next; } printf("%4d\n",p->data); }