单链表实现约瑟夫环

约瑟夫环的问题可以分成四个部分:

1、一群人围在一起坐成环状                          (建环)

2、从某个编号开始报规定的数                      (找到相对应的数)

3、数到某个数的时候,此人出列                  (删除找到的数)

4、一直循环,直到剩下最后一个人              (解环)

看代码:

#include<windows.h>
#include<stdio.h>
#include<assert.h>
typedef int DataType;
typedef struct Node
{
	DataType data;
	struct Node* next;
}Node, *pNode, List, *pList;
void InitLinkList(pList* pplist)//初始化
{
	assert(*pplist != NULL);
	*pplist = NULL;
}
pNode BuyNode(DataType d)
{
	pNode p = malloc(sizeof(Node));
	p->data = d;
	p->next = NULL;
	return p;
}
void PushBack(pList* pplist, DataType d)//尾插
{
	assert(pplist != NULL);
	pNode p = BuyNode(d);
	if (*pplist == NULL)
	{
		*pplist = p;
	}
	else
	{
		pList cur = *pplist;
		while (cur->next != NULL)
		{
			cur = cur->next;
		}
		cur->next = p;
	}
}
void PrintLinkList(pList plist)//打印
{
	while (plist != NULL)
	{
		printf("%d--->", plist->data);
		plist = plist->next;
	}
	printf("over\n");
}
pNode JosephCircle(pList *plist, int k)
{
	pList phead1 = *plist;
	pList phead = *plist;
	while (phead->next != NULL)
	{
		phead = phead->next;
	}
	phead->next = *plist;//建环
	while (phead1->next != phead1)
	{
		int x = k - 1;
		pList cur = phead1;
		pList pre = NULL;
		while (x)
		{
			pre = cur;
			cur = cur->next;
			x--;
		}//找到相对应的数
		pre->next = cur->next;//删除找到的数
		phead1 = cur->next;//删除一个数后,下一个节点从1开始
		free(cur);//删除后,需要释放
		cur = NULL;
	}
	phead1->next = NULL;//解环
	return phead1;
}
void test()
{
	pList s;
	InitLinkList(&s);
	PushBack(&s, 1);
	PushBack(&s, 2);
	PushBack(&s, 3);
	PushBack(&s, 4);
	PushBack(&s, 5);
	PushBack(&s, 6);
	PushBack(&s, 7);
	pList ret = JosephCircle(&s, 2);
	PrintLinkList(ret);
}
int main()
{
	test();
	system("pause");
	return 0;
}

重点:

1.报k时,引动k-1个单位,当移动第k-1个单位后,这是(k-1)--为0,这时就要将k重新定义为原来的值,方便下一次重新循环。

2.要将删除的那个节点的下一个节点改成下一次循环的第一个节点。

3.删除一个节点后一定要释放。

4.构成一个环最后需要解环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值