话都在代码里
题目
//约瑟夫环的循环链表解法
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
struct node//链表结构体的创建。
{
int data;
struct node* next;
};
int main(void)
{
int array[100];//循环输出数组
int n, m;//猴子个数,淘汰间序
struct node* head, * tail, * p, * q;//q是删除时用来移动链表的。,heand,tail,p是构造链表
int count = 0;//表示数组下标。
int i;//数猴子个数到达删除位置没有。
///创建空间三部曲
head = (struct node*)malloc(sizeof(struct node));
head->data = -1;
head->next = NULL;
///
while (1)
{
printf("请输入猴子个数,淘汰次序\n");
scanf_s("%d %d", &n, &m);
if (n==0 || m==0)//输入为0 0退出,否则继续。
{
free(head); //代表啥也没做,清除链表。
break;
}
else
{//尾插法,建立链表
tail = head; //开始时候头等于尾
for (i = 0; i < n; i++)
{
p = (struct node*)malloc(sizeof(struct node));
p->data = i + 1;//赋值,但不用data里面的值做判断。
tail->next = p;//形参闭环
p->next = head->next;//核心代码
tail = p;
}
//开始查找的初始化
p = head->next;//后节点
q = tail;//前节点
i = 1;
//开始判断
while (p != q)//是否只剩下一个节点(除头节点外)
{
if (i == m)//如果循环到指定位置
{
q->next = p->next;//q保存了p的下一个节点。
free(p); //删除节点
p = q->next;
i = 1;//初始化
}
else//否则循环继续
{//两个指针位置的转移。
q = p;
p = p->next;
i++;
}
} //选王完毕,脱离小的while循环。
//will会自然循环和初始化。所以用不for循环赋值。
array[count] = p->data;//while外面已经初始化为0.
count++;
free(p);//每循环一次就释放一次p节点,下次while循环再建立。注意!!!是释放p所指的空间
head->next = NULL;//头节点指像空。
}
}
for (i = 0; i < count; i++)
{
printf("%d\n", array[i]);
}
free(head);
return 0;
}