單向循環鏈表(約瑟夫環)
#include<stdlib.h>
#define N 10
typedef struct node{
int data;
struct node * next;
}ElemSN;
ElemSN*Createlink(int a[],int n){
int i;
ElemSN*h=NULL,*p,*t;
for(i=0;i<N;i++){
p=(ElemSN*)malloc(sizeof(ElemSN));
p->data=a[i];
if(!h)
h=t=p;
else
p->next=h;
t=t->next=p;
}
return t;
}//創建單向循環鏈表
ElemSN*Fun(ElemSN*t,int s){
int i;
ElemSN*h1=NULL,*t1,*h; //t1是行鏈表的尾結點指針,h是建立新鏈表的結點(出約瑟夫環的結點),h1新鏈表的頭結點
while(t-t->next){//截止條件是環中只剩下一個結點,循環結束直接出環
for(i=0;i<s-1;i++)
t=t->next; //每隔幾個結點出環S,指針t的下一個加點就是要出環的結點
h=t->next; //h表示要出環的結點
t->next=h->next;//出環
h->next=NULL;//指針域為空斷鏈,出環的結點和約瑟夫環沒有聯系
if(!h1)//新鏈表為空時,頭結點h1,尾結點t1,在同一個結點上
h1=t1=h;
else//新鏈表頭結點不空,出環的結點h掛在新鏈表的尾結點上,尾結點t1後移,繼續標誌鏈表的尾結點
t1=t1->next=h;
}
if(!h1)//環中只剩下一個結點,直接出環,判斷新鏈表為空,說明約瑟夫環中只有一個結點
h1=t;//環中的結點直接為新鏈表的頭結點
else{
t1->next=t; //新鏈表頭結點不空,出環的結點直接掛到新鏈表的尾結點上,
t->next=NULL;//指針域為空,否則新鏈表中有為結點的next是自己,在尾結點上出現一個環(循環)
}
return h1;
}
void Printlink(ElemSN*h){
ElemSN*p;
for(p=h;p;p=p->next)
printf("%2d\n",p->data);
}
int main(void){
int a[N]={1,2,3,4,5,6,7,8,9,10};
int s;
ElemSN*head;
head=Createlink(a,9);
printf("請輸入s=");
scanf("%2d",&s);
head=Fun(head,s);
Printlink(head);
}
單向循環鏈表(約瑟夫環)