无头单向链表尾节点的指针域保存头节点的地址, 就可以形成单向循环链表。
用单向循环链表解决约瑟夫问题:
通过一定的规律找出一个最终的值。
#include "stdio.h"
#include "stdlib.h"
#define N 5
typedef struct node_t
{
int data;
struct node_t *next;
} link_t;
int main(int argc, char const *argv[])
{
link_t *p = (link_t *)malloc(sizeof(link_t)); //创建单向无头节点
if (p == NULL)
{
printf("malloc err\n");
return -1;
}
p->data = 1; //初始化头节点
p->next = NULL;
link_t *tail = NULL;
tail = p;//定义一个指针指向头节点p
for (int i = 1; i < N; i++) //循环创建节点
{
tail->next = (link_t *)malloc(sizeof(link_t));//头节点指向新创建的节点
if (tail->next == NULL)
{
printf("malloc node err\n");
return -1;
}
tail = tail->next; //tail指向新创建的节点
tail->data = i + 1; //初始化
tail->next = NULL;
}
tail->next = p; //首尾相连得到一个单向循环节点
//解决约瑟夫问题
int start_num = 1; //定义开始的位置
int n = 2; //数数的个数
for (int i = 0; i < start_num - 1; i++) //将头指针移动到定义开始的位置
p = p->next;
link_t *pdel = NULL;
while (p != p->next) //循环删除节点
{
for (int i = 0; i < n - 1; i++)//定位到要删除节点的前一个节点
p = p->next;
pdel = p->next;//让pdel指向要删除的节点
p->next = pdel->next;
free(pdel);
pdel = NULL;
}
printf("king is %d\n", p->data);
return 0;
}