环形单链表的约瑟夫问题
题目:
约瑟夫环(约瑟夫问题)是一个数学的应用问题:
已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌只剩一个人。
解题思路:
1、如果链表为空,或者链表节点数为1,return head;
2、环形链表中循环遍历每个节点,不断转圈,不断让每个节点报数
3、当报数达到m时,删除当前报数的节点
4、删除节点后重新连接为环形
5、待剩余最后一个结点时return结束。
链表结点结构定义:
typedef struct Node
{
int data;
struct Node* next;
}node, *pLinkedList;
算法代码:
Node* josephus(pLinkedList head, int m)
{
if (head == NULL || head->next == head)
return head;
pLinkedList last = head;
//将last设置为head前一个节点
while (last->next != head)
{
last = last->next;
}
int count = 0;
while (head != last)
{
//报数够m时删除当前节点,即head节点
if (++count == m)
{
last->next = head->next;
free(head);
head = NULL;
count = 0;//count重新置为0
}
else
{
last = last->next;
}
head = last->next;
}
return head;
}