//CycList:循环单链表 #include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct Node{ DataType data; struct Node *next; }ListNode,*LinkList; //创建一个不带头结点的循环单链表 LinkList CreateCycList(int n){ DataType e; LinkList head=NULL; ListNode *p,*q; int i; i=1; while(i<=n){ printf("请输入第%d个元素:",i); scanf("%d",&e); if(i==1){ //创建第一个结点 head=(LinkList)malloc(sizeof(ListNode)); head->data=e; head->next=NULL; q=head; //指针q指向链表的最后一个结点 }else{ p=(ListNode *)malloc(sizeof(ListNode)); p->data=e; p->next=NULL; q->next=p; //将新结点连接到链表中 q=p; //q始终指向最后一个结点 } i++; } if(q!=NULL) q->next=head; //将最后一个结点的指针指向头指针,使其形成一个循环链表 return head; } //输出循环链表的每一个元素 void DisplayCycList(LinkList head){ ListNode *p; p=head; if(p==NULL){ printf("该链表是空表"); return; } while(p->next!=head){ printf("%4d",p->data);//如果不是最后一个结点,输出该结点 p=p->next; } printf("%4d ",p->data);//输出最后一个结点 } //将两个链表head1和head2连接在一起形成一个循环链表 LinkList Link(LinkList head1,LinkList head2){ ListNode *p,*q; p=head1; while(p->next!=head1)//指针p指向链表的最后一个结点 p=p->next; q=head2; while(q->next!=head2)//指针q指向链表的最后一个结点 q=q->next; p->next=head2;//将第一个链表的尾端连接到第二个链表的第一个结点 q->next=head1;//将第二个链表的尾端连接到第一个链表的第一个结点 return head1; } void main_Link(){ LinkList h1,h2; int n; printf("创建一个循环单链表h1: "); printf("请输入元素个数: "); scanf("%d",&n); h1=CreateCycList(n); printf("创建一个循环单链表h2: "); printf("请输入元素个数: "); scanf("%d",&n); h2=CreateCycList(n); printf("输出循环单链表h1 "); DisplayCycList(h1); printf("输出循环单链表h2 "); DisplayCycList(h2); h1=Link(h1,h2); printf("输出连接后的循环单链表h1+h2 "); DisplayCycList(h1); system("pause"); } //*************************** //在长度为n的循环单链表中,从第k个人开始报数,数到m的人出列 void Josephus(LinkList head,int n,int m,int k){ ListNode *p,*q; int i; p=head; for(i=1;i<k;i++){ //从第k个人开始报数 q=p; p=q->next; } while(p->next!=p){ for(i=1;i<m;i++){ //数到m的人出列 q=p; p=q->next; } q->next=p->next; //将p指向的结点删除,即报数为m的人出列 printf("%4d",p->data); free(p); p=q->next; //p指向下一个结点,重新开始报数 } printf("%4d ",p->data); } LinkList CreateCycList_(int n) { LinkList head=NULL; ListNode *s,*r; int i; for(i=1;i<=n;i++) { s=(ListNode*)malloc(sizeof(ListNode)); s->data=i; s->next=NULL; if(head==NULL) head=s; else r->next=s; r=s; } r->next=head; return head; } void main_Josephus() { LinkList h; int n,k,m; printf("输入环中人的个数n="); scanf("%d",&n); printf("输入开始报数的序号k="); scanf("%d",&k); printf("报数为m的人出列m="); scanf("%d",&m); h=CreateCycList_(n); Josephus(h,n,m,k); system("pause"); } void main(){ main_Link(); main_Josephus(); }