資料結構—約瑟夫環問題(迴圈單鏈表)
阿新 • • 發佈:2018-11-04
n個數據元素構成一個環,從環中任意位置開始計數,計到m將該元素從表中取出,重複上述過程,直至表中只剩下一個元素。
解題思路:用一個無頭結點的迴圈單鏈表來實現n個元素的儲存。迴圈單鏈表:尾指標指向頭結點。這樣指標可以迴圈移動。
可以使用兩個指標來操作,將指標q指向需要操作的結點上,指標p指向需要操作結點的前一個結點。
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <malloc.h> 4 #include <math.h> 5 #define NULL 0 6typedef struct LNode 7 { 8 int num;///編號 9 struct LNode *next; 10 } LNode, *Linklist; 11 Linklist head,tail; 12 void Createlist(int n)///建立含有n個結點的單迴圈連結串列 13 { 14 int i; 15 Linklist p,q; 16 head=(Linklist)malloc(sizeof(LNode)); 17 q=head; 18 q->num=1; 19 for(i=2; i<=n; i++) 20 { 21 p=(Linklist)malloc(sizeof(LNode)); 22 p->num=i; 23 q->next=p; 24 q=p; 25 } 26 p->next=head; 27 tail=p;///尾指標要指向頭結點 28 } 29 void Outlist(int k) 30 { 31 int i; 32 Linklist p,q; 33 p = head; 34 for(i=1; i<k-1; i++)///迴圈k-2次 35 { 36 p = p->next;///指向需要操作元素的前一個指標 37 } 38 q = p->next;///指向需要操作元素的指標 39 while(q != p) 40 { 41 printf("%3d",q->num); 42 p->next = q->next;///刪除q所指向的元素 43 for(i=1; i<k; i++)///因為要經過已經刪除的元素,所以需要多刪除一次 44 { 45 p = p->next; 46 } 47 q = p->next; 48 } 49 printf("%3d\n",q->num); 50 51 } 52 int main() 53 { 54 int k,n; 55 printf("---------------約瑟夫環問題--------------\n"); 56 printf("\n請輸入總人數和從第幾個人開始報數n,k:\n"); 57 scanf("%d%d",&n,&k); 58 Createlist(n); 59 printf("\n出隊的次序:\n"); 60 Outlist(k); 61 return 0; 62 }
我看了一下我同學的做法,可以p直接使用尾指標,而q來自頭指標,這樣在遍歷的時候,p指標一直會在q指標之前。
1 void Outlist(int k) 2 { 3 int i; 4 Linklist p,q; 5 q = head; 6 p = tail; 7 for(i=1;i<k;i++) 8 { 9 p = p->next; 10 q = q->next; 11 } 12 while(q != p) 13 { 14 printf("%3d",q->num); 15 p->next = q->next; 16 q = p->next; 17 for(i=1;i<k;i++) 18 { 19 p = p->next; 20 q = q->next; 21 } 22 } 23 printf("%3d\n",q->num); 24 }