#单向循环链表实现约瑟夫环
#include <stdio.h>
#include <stdlib.h> //提供malloc、free函数原型
/* 结点数据域数据类型 */
typedef int ElemType;
/* 链表结点结构体 */
typedef struct LNode
{
ElemType data; //数据域
struct LNode* next; //指针域
}LNode;
typedef LNode* LinkList; //指向链表结点的指针
///*———————函数声明———————*///
LinkList Create(int m);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃创建一个含m个结点的单向循环链表 ┃
┃并对每个结点编号后,返回其头结点 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
void deleteLink(LinkList head,int s,int n,int m);
/*━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ 实现约瑟夫环的函数 ┃
┃ 参数表分别为 ┃
┃ head:单向环表的头指针 ┃
┃ s:从第s位开始 ┃
┃ n:间隔n位删除 ┃
┃ m:环表长度 ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━*/
///*———————主函数———————*///
int main()
{
int m,s,n;
LinkList head; //为链表定义一个头指针
//输入m,s,n
printf("请输入m=");
scanf("%d",&m);
printf("\n请输入s=");
scanf("%d",&s);
printf("\n请输入n=");
scanf("%d",&n);
printf("\n");
//创建链表并求解问题
head=Create(m);
deleteLink(head,s,n,m);
system("pause");
return 0;
}
///*——————函数定义———————*///
LinkList Create(int m)
{
LinkList rear,head,tmp;
int i=0;
rear=(LNode*)malloc(sizeof(LNode));
if(rear==NULL)
{
printf("内存分配失败!");
}
head=rear;
//尾插法创建一个有m个结点的单链表
for(i=1;i<=m;i++)
{
tmp=(LNode*)malloc(sizeof(LNode));
if(tmp==NULL)
{
printf("内存分配失败!");
}
tmp->data=i; //为每个结点按顺序编号
rear->next=tmp; //新节点插在尾巴
rear=tmp;
}
//将尾结点和第一个节点连接起来,成为单向环表
rear->next=head->next;
//返回单向环表的头指针
return head;
}
void deleteLink(LinkList head,int s,int n,int m)
{
int i,j;
LinkList pre,tmp;
pre=head->next;
//找到起始结点
for(i=1;i<s;i++)
{
pre=pre->next;
}
for(j=1;j<=m;j++) //循环m次,输出全部结点
{
//循环间隔n的长度找到下一个待删除结点的pre
for(i=0;i<n-2;i++)
{
pre=pre->next;
}
printf("第%d位:%-3d\n",j,pre->next->data);
//输出待删除结点的编号
tmp=pre->next; //现在pre为待删除结点的前一个结点,tmp为待删除结点
pre->next=tmp->next; //使tmp的前后结点连接
free(tmp); //删除tmp结点
pre=pre->next; //指向下一结点
}
}
版权声明:本文为qq_43810346原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。