約瑟夫環 C語言 單循環鏈表
阿新 • • 發佈:2017-08-10
node 前驅 輸入 truct sizeof -- 描述 reat 約瑟夫
/*---------約瑟夫環---------*/ /*---------問題描述---------*/ /*編號為1,2,…,n的n個人圍坐一圈,每人持一個密碼(正整數)。 一開始任選一個正整數作為報數上限值m, 從第一個人開始自1開始順序報數,報到m時停止。 報m的人出列,將他的密碼作為新的m值,從他的下一個人開始重新從1報數, 如此下去,直至所有人全部出列為止。試設計一個程序求出列順序。*/ /*---------問題分析---------*/ /*n個人圍坐一圈,且不斷有人出列,即頻繁刪除,應用單循環鏈表。 有因為報數的過程是計數的過程,每個數據結點計1,因此不帶頭結點合適。 又因為第一次報數的上限是任選的正整數,有可能報到第一個人時出列,為刪除第一個結點, 須知其前驅結點的位置,即尾結點的位置,因此應設尾指針,不設頭指針*/ #include<stdio.h> #include<stdlib.h> typedef struct lnode{ int num; //序號 int key; //密碼 struct lnode *next; }LNode,*LinkList; void CreatList(LinkList &L) {//建立含有n個結點的不帶頭結點的單循環鏈表,L為尾指針 int n; int i; LinkList s,p; printf("請輸入人數:"); scanf("%d",&n); while(n<=0) { printf("人數太少!請重新輸入:"); scanf("%d",&n); } L=(LinkList)malloc(sizeof(LNode)); //建立第一個結點,輸入第一個人的信息 L->num=1; printf("請輸入第1個人的密碼:"); scanf("%d",&L->key); p=L;//p指向目前鏈表的尾結點,之後新建結點均插入表尾 for(i=2;i<=n;i++) { s=(LinkList)malloc(sizeof(LNode)); s->num=i; printf("請輸入第%d個人的密碼:",i); scanf("%d",&s->key); p->next=s; //將新結點*s插入鏈表尾部,p指向新結點 p=s; } p->next=L; //尾結點的next指向表首結點,構成循環鏈表 L=p; //L指向尾結點,即鏈表為設尾指針的鏈表 } void Joseph(LinkList &L) { int key,i; LinkList p,q; printf("請輸入正整數:"); scanf("%d",&key); p=L; while(p->next!=p) { for(i=1;i<key;i++) { p=p->next; } q=p->next; printf("%d ",p->num); p->next=q->next; key=q->key; free(q); } printf("%d ",p->num); } int main() { LinkList L; printf("-----------------------------約瑟夫環-----------------------------\n"); CreatList(L); Joseph(L); }
約瑟夫環 C語言 單循環鏈表