步骤:
1、生成循环链表
2、定位到需要删除的节点(nowNode),并记录上一个节点(preNode)
3、确保链表长度不为零。根据步长,计算删除节点位置。删除前保存下一个节点(nexNode)
4、恢复链表,跳到3。
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define NUM 10 //节点数
typedef struct student
{
int data;
struct student* next;
}Node;
// 约瑟夫环, 从k开始数,数到m出链表,m+1继续,直到所有出
Node* JOSEPHUS(int k, int m)
{
/* 循环链表创立 */
Node* head = (Node*)malloc(sizeof(Node));
if (NULL == head)
{
printf("The head can't be created.\n");
exit(1);
}
head -> next = head;
head -> data = 0;
Node* curr = head;
for (int i = 1; i < NUM; i++)
{
Node* newNode = (Node*)malloc(sizeof(Node));
if (NULL == newNode) exit(1);
newNode -> data = i;
newNode -> next = head;
curr -> next = newNode;
curr = newNode;
}
/* 根据k值定位到开始 */
Node* preNode = curr; //k-1位置节点
Node* nowNode = head; //k 位置节点
while (k--)
{
preNode = preNode -> next;
nowNode = nowNode -> next;
}
/* 删除节点 */
int num = NUM;
while (num--)
{
int stepLen = m; //步长
Node* nexNode = NULL;
while (stepLen--)
{
preNode = preNode -> next;
nowNode = nowNode -> next;
}
printf("%d->", nowNode->data);
nexNode = nowNode -> next; //删除当前节点前,保存后节点位置
free(nowNode);
// 删除之后恢复链表状态
preNode -> next = nexNode;
nowNode = nexNode;
}
return head;
}
int main(void)
{
Node* head = JOSEPHUS(2, 3);
return 0;
}