直接上代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
typedef struct ListNode
{
int data;
struct ListNode * next;
}ListNode;
void create(ListNode * firstNode, int m) //创建单向循环链表
{
if (firstNode == NULL)
{
return;
}
int i;
ListNode * pre = firstNode;
for (i = 2; i <= m; i++)
{
ListNode * node = (ListNode *)malloc(sizeof(ListNode));
node->data = i;
pre->next = node; //让前一个节点的next域为刚刚生成的node的地址
pre = node;
}
pre->next = firstNode;
}
void show(ListNode * firstNode) //显示循环链表的节点编号
{
if (firstNode == NULL)
{
return;
}
int i;
printf("创建的单向环表节点编号依次为:\n");
ListNode * p = firstNode;
printf("%d\n", p->data);
p = p->next;
while (p != firstNode)
{
printf("%d\n", p->data);
p = p->next;
}
}
ListNode * joseph(ListNode * firstNode, int m, int s, int n) //一共m个结点, 从第s个结点开始计数到第n个结点
{
if (firstNode == NULL || s > m || s < 1)
{
return;
}
int i;
ListNode * current = firstNode;
for (i = 1; i <= s-1; i++)
{
current = current->next;
}
printf("输出第s个结点:\n");
printf("%d\n", current->data);
int j;
for (j = 2; j <= n-1; j++) //current已经为当前节点,所以j从2开始(下一个节点)
{
current = current->next; //走到第n个结点的前一个节点
}
printf("输出第n个结点:\n");
printf("%d\n", current->next->data);
//删除第n个结点
ListNode * nodeN = current->next;
current->next = nodeN->next;
if (nodeN == firstNode)
{
firstNode = nodeN->next;
}
nodeN->next = NULL;
free(nodeN);
show(firstNode);
return firstNode;
}
int main()
{
int m, s, n, r; //从第s个结点开始计数到第n个结点
printf("输入单向环表节点数m:\n");
scanf("%d", &m);
printf("输入开始计数的节点编号s:\n");
scanf("%d", &s);
printf("输入计数到的节点编号n:\n");
scanf("%d", &n);
ListNode * firstNode = (ListNode *)malloc(sizeof(ListNode));
firstNode->data = 1;
create(firstNode, m);
show(firstNode);
firstNode = joseph(firstNode, m, s, n);
show(firstNode);
return 0;
}