一群人围成一圈,选定一个数,从第一个人数,数到那个数的时候,对应的那个人紫砂,然后把西内的人挪走,空下来的位置接上,然后重新开始数,循环下去
链表
链表是一个循环单链表,给定一个数字让链表初始化,再给一个数字来算每到第几个节点就删除对应的节点,然后被删节点的前一个节点与后一个节点连接,循环下去
代码
节点类型
struct ListNode
{
int L_num;
ListNode* next;
ListNode() :L_num(0), next(nullptr) {}
ListNode(int num) :L_num(num), next(nullptr) {}
}; //节点类型
链表初始化,显示,已经执行约瑟夫算法的函数
ListNode* initialList(int num) //初始化链表,参数为节点数量
{
ListNode* head = nullptr;
ListNode* tail = nullptr;
for (int i = 1; i <= num; i++)
{
if (!head) //如果没有表头,则给head头指针一个指向新建的第一个节点
{
head = tail = new ListNode(i);
}
else //已有表头,新建节点让tail给它们接上
{
tail->next = new ListNode(i);
tail = tail->next;
}
}
tail->next = head;
return head;
}
void printList(ListNode* head) //打印链表每个节点的数据
{
ListNode* p = head;
while (p->next != head)
{
cout << p->L_num << " -> ";
p = p->next;
}
cout << p->L_num << endl;
}
ListNode* suicideSquad(ListNode* head, int num, int n) //进行约瑟夫算法,参数第一个为链表头指针,第二个是节点数量,第三个是删除第n的节点
{
ListNode* p = head;
if (n < 1) //防止乱输入
{
cout << "都活了,再见" << endl;
exit(0);
}
int m = num % n; //用于在循环移动到删除的节点前一个
while (p->next != p)
{
for (int i = 1; i < m; i++)
{
p = p->next;
}
ListNode* temp = p->next; //节点删除再连接
ListNode* q = temp->next;
p->next = q;
p = q;
delete temp;
temp = nullptr;
}
head = p; //将删除后p的指针给head,不加head的指针指向的节点已经被删除和释放,访问会错误
return head; //返回head
}
main一些东西
void test()
{
ListNode* head = nullptr;
int num = 41;
cout << "紫砂前" << endl;
head = initialList(num);
printList(head);
cout << endl;
cout << "紫砂后" << endl;
head = suicideSquad(head, num, 3);
printList(head);
}
int main()
{
test();
cin.get();
return 0;
}
紫砂小队嗯嗯