> 文章列表 > 实验一:第五题循环链表的应用(约瑟夫回环问题)

实验一:第五题循环链表的应用(约瑟夫回环问题)

实验一:第五题循环链表的应用(约瑟夫回环问题)

n个数据元素构成一个环,从环中任意位置开始计数,计到m将该元素从表中取出,重复上述过程,直至表中只剩下一个元素。

提示:用一个无头结点的循环单链表来实现n个元素的存储。

参考代码:

#include<stdio.h>  //声明
#include<malloc.h>
#define ERROR 0
#define OK 1    //宏定义 oK 相当于 1
typedef  int ElemType; //定义表元素的类型
typedef struct LNode   //线性表的单链表存储
{ElemType data;       //数据元素datastruct LNode *next;   //指向下一个节点的指针next
} LNode,*LinkList;      //定义单链表别名 LinklistLinkList Creat(int t)   //创建长度为 t 的单向循环链表
{int n;    //整型变量LinkList p1,p2,head; p1=(LinkList)malloc(sizeof(LNode));  //分配一个内存,大小是LNode的大小,p2=(LinkList)malloc(sizeof(LNode));  //并将这个内存地址转化为Link型,然后将赋给 p1,p2head = NULL;   //链表为空n = 1;   //从1开始while(n<=t)  // n<=t 循环{p1->data = n;  // n 赋值给p1所指向的数据元素dataif(n==1)    //若 n 等于 1head = p1;  //p1 赋值给headelse        //不等p2->next = p1;  //p1 赋值给p2所指向的nextp2 = p1;  //p1 赋值给p2if(n!=t)  // 若 n 不等于 tp1 = (LinkList)malloc(sizeof(LNode)); //为p1重新分配一个是LNode大小的内存n++;  //自增}p2->next = head;   //将最后一个节点p2的指针指向头节点 headreturn head;    //返回头节点}
LinkList Start(LinkList L,int k)  //start函数,用于找链表中第 K 个节点的位置
{int i;i=1;while(i!=k){L=L->next;  //L 指向下一个节点赋值给 L i++;        //自增,i+1}return L;  //返回该节点的指针}
LinkList Delete(int n,int m,LinkList L)  //Delete函数用于删除每个 m 节点
{int i,j,k;LinkList p;p=L;k=0;while(n>1){j=0;for(i=1+k; i<=n; i++){if((i+1)%m==0)  //i+1对 m 取余{printf("%d ",p->next->data);  // 输出p的下一个的节点.p->next=p->next->next;   // 把 p的下一个的下一个赋给p的下一个.i++;j++;}p=p->next;  // p 的下一个指针赋值给 pk=i%m;      // i 对 m 取余赋值给 K}n=n-j;}printf("%d\\n",p->data);  //输出被删除的节点数据return p;   //返回最后一个节点的指针
}
int main()
{int m,n,k;scanf("%d%d%d",&n,&m,&k); //从输入读入n,m,K三个整数LinkList L,cur;L=Creat(n);     //调用Creat 函数创建一个长度为 n 的单向循环链表cur=Start(L,k); //调用 Start 函数找到第 K 个节点的位置,赋值给 cur 传给Delete函数Delete(n,m,cur); //调用 Delete函数,进行链表节点的删除操作return 0;  //程序退出
}