資料結構——簡單約瑟夫環
阿新 • • 發佈:2018-12-12
約瑟夫環問題
問題描述:約瑟夫環問題是,編號為1,2,3,…,n的n個人按順時針方向圍坐一圈,每人持有一個密碼。開始時任選一個正整數作為報數上限值m,從第一個人開始順時針方向自1開始順序報數,報到m時停止報數。報m的人出列,將他的密碼作為新的m值,從他在順時針方向上的下一個人開始重新從1報數,如此下去,直至所有人全部出列為止。
基本要求:利用單鏈表儲存結構模擬此問題,按照出列順序列印各人的編號。
測試資料:M的初值為20,n=7,7個人的密碼依次為3,1,7,2,4,8,4。則首先出列的人是6號,依次正確的出列順序應該為6,1,4,7,2,3,5。
實現提示:要求使用者指定報數上限值,然後讀取每人的密碼。此問題所用迴圈連結串列不需要頭結點。
思路:
其中包含一些對連結串列的基本操作,新增,輸出,刪除等。
程式碼:
#include <stdio.h> #include <stdlib.h> typedef struct _node{ int xuhao; int mima; struct _node *next; }Node;//定義結點的結構體型別 typedef struct _list{ Node *head; Node *tail; Node *mark; Node *smark; }List;//自定義指向連結串列的一些指標 void add(List *pList,int x,int m); void print(List *pList); void shanchu(List *pList,int x); void printw(List *pList); int main(int argc,const char*argv[]) { int m,n; scanf("%d %d",&m,&n); int a[n+1]; for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } List list; list.head=NULL; for(int i=1;i<=n;i++)//構造結點個數為n的連結串列 { add(&list,i,a[i]); } //printw(&list); //檢查連結串列是否新增正確 int number=n;//連結串列中結點的個數,用作迴圈的終止條件 list.mark=list.head; while(number>0) { int yushu=m%number;//取模運算,找到要輸出的結點的位置 for(int i=yushu;i>1;i--)//迴圈使mark指向所要操作的結點 { if(list.mark->next) { list.mark=list.mark->next; } else { list.mark=list.head; } } list.smark=list.mark; m=list.mark->mima; number--;//每次重置m,number減一 print(&list); if(list.mark->next){ list.mark=list.mark->next; }else{ list.mark=list.head; } shanchu(&list,list.smark->xuhao); //printw(&list);//檢驗輸出每次刪除之後的連結串列是否正確 } return 0; } void add(List *pList,int x,int m)//新增單個結點到連結串列中 { Node *p=(Node *)(malloc)(sizeof(Node)); p->xuhao=x; p->mima=m; if(pList->head){ pList->tail->next=p; pList->tail=p; }else{ pList->head=p; pList->tail=p; } p->next=NULL; } void print(List *pList)//輸出引數中pList所指的mark所指的序號 { printf("%d\t",pList->mark->xuhao); } void shanchu(List *pList,int x)//刪除單個結點 { Node *p=pList->head; Node *q; while(p->xuhao!=x&&p) { q=p; p=p->next; } if(p==pList->head){ //當刪除的結點是head所指向的第一個結點時 pList->head=p->next; }else { q->next=p->next; } free(p); } void printw(List *pList)//輸出整個連結串列 { Node *p=pList->head; while(p) { printf("%d\t",p->mima); p=p->next; } printf("\n"); }