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; //数据元素data
struct LNode *next; //指向下一个节点的指针next
} LNode,*LinkList; //定义单链表别名 Linklist
LinkList Creat(int t) //创建长度为 t 的单向循环链表
{
int n; //整型变量
LinkList p1,p2,head;
p1=(LinkList)malloc(sizeof(LNode)); //分配一个内存,大小是LNode的大小,
p2=(LinkList)malloc(sizeof(LNode)); //并将这个内存地址转化为Link型,然后将赋给 p1,p2
head = NULL; //链表为空
n = 1; //从1开始
while(n<=t) // n<=t 循环
{
p1->data = n; // n 赋值给p1所指向的数据元素data
if(n==1) //若 n 等于 1
head = p1; //p1 赋值给head
else //不等
p2->next = p1; //p1 赋值给p2所指向的next
p2 = p1; //p1 赋值给p2
if(n!=t) // 若 n 不等于 t
p1 = (LinkList)malloc(sizeof(LNode)); //为p1重新分配一个是LNode大小的内存
n++; //自增
}
p2->next = head; //将最后一个节点p2的指针指向头节点 head
return 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 的下一个指针赋值给 p
k=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; //程序退出
}