迴圈鏈表,最後的尾指標指到頭結點上,雙向迴圈鏈表就是再加個pre指標。
約瑟夫環的問題:設編號分別為:1,2,3,...n的n個人圍坐在一圈。約定序號為k(1<=k<=n)的人從1開始計數,數m的那個人出列,他的下一位又開始從1開始計數,數到m的那個人又出列,以此類推,直到所有的人都出列。
例如:設 n = 8,k= 3 , m = 4時,出列序列為:6 2 7 4 3 5 1 8
演算法思路:用一個不帶頭結點的迴圈鏈表來處理Josephu問題:先構成一個有n個節點的單迴圈鏈表,然後從第k結點起從1計數,記到m時,對應的結點從鏈表中刪除;然後再從被刪除結點的下一個結點起又從1開始計數.....,直到所有結點都出列時,演算法結束。
#include <stdio.h>#include <errno.h>#include <stdlib.h>#define N 10typedef int datatype;typedef struct node { datatype data; struct node * next;}linknode ,*linklist;linklist create(){ linklist H; if((H = (linklist)malloc(sizeof(linknode)))==NULL) { perror("malloc"); exit(-1); } H->next = H; H->data = 1; printf("create\n"); return H;}int insert(linklist H,datatype data , int pos){ int i; linklist q; linklist p = NULL; p = H; if((pos<0)) { printf("insert error\n"); return -1; } if((q = (linklist)malloc(sizeof(linknode))) == NULL ) { perror("malloc"); exit(-1); } while(pos--) p=p->next; q->data = data; q->next = p->next; p->next = q; return 0;}int show(linklist H,int k,int m){ int i = k-2; linklist p,q; p = H; while(i--) p = p->next; while(p != p->next) { for(i = 0;i < m-1; i++) p = p->next; q = p; p = p->next; q ->next = p->next; printf("data =%d\n",p->data); free(p); p = q->next; } printf("data =%d\n",p->data); return 0;}int main(int argc,char * argv[]){ int n,m,k,i = 0; int ret; linklist H; H = create(); scanf("%d",&n); scanf("%d",&m); scanf("%d",&k); for(i = 2;i < n+1;i++) { ret = insert(H,i,i-2); if(ret ==-1) printf("insert error\n"); } printf("**********create linklist*************\n"); show(H,m,k); return 0;}