单链表实现约瑟夫环

何谓约瑟夫环?
约瑟夫环是一个 数学的应用 问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列,剩下最后一个人。

举个例子:

按照以上规则,从0开始数,最后剩下的是数字5。


函数定义:
Node*JosephCycle(PNode*ppHead, int k,int m);//其中k为起始位置,m为要删除的位置

代码如下:
头文件SList.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct SListNode
{
	DataType data;
	 struct SListNode*pNext;
}Node, *PNode;

  
  
PNode* BuyNode(DataType data);//创建节点
void DestroyNode(PNode** ppHead);//销毁节点
void IntiSList(PNode*pHead);//初始化
Node* PushBackSList(PNode* ppHead, DataType data);// 尾插
Node*JosephCycle(PNode*ppHead, int k,int m);//实现约瑟夫环
SList.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include"SList.h"

PNode* BuyNode(DataType data)
{
	Node*pNewNode = (Node*)malloc(sizeof(Node));
	if (pNewNode != NULL)
	{
		pNewNode->data = data;
		pNewNode->pNext = NULL;
	}
	return pNewNode;
}
void DestroyNode(PNode* ppHead)
{
	if (ppHead == NULL)
		return;
	if (*ppHead == NULL)
		return;
	free(*ppHead);
}
void IntiSList(PNode*pHead)
{
	assert(pHead);
	*pHead = NULL;
}
Node* PushBackSList(PNode* ppHead, DataType data)
{
	assert(ppHead);
	Node*pTailNode = *ppHead;
	if (*ppHead == NULL)
	{
		*ppHead=BuyNode(data);
		return *ppHead;
	}
	else
	{
		while (pTailNode->pNext)
		{
			pTailNode = pTailNode->pNext;
		}
		pTailNode->pNext = (BuyNode(data));
	}
	return pTailNode->pNext;
}
Node*JosephCycle(PNode*ppHead,int k,int m)
{
 assert(ppHead);
 Node*pDel = NULL;
 Node*pCur = *ppHead;
 while (k--)//从第k个元素开始
 {
  pCur = pCur->pNext;
 }
 int i = m;
 while (1)
 {
  if (pCur == pCur->pNext)//只剩一个元素
  {
   pCur->pNext = NULL;
   printf("%c\n", pCur->data);
   break;
  }
  while (m>1)//数到m个元素删除
  {
   pCur = pCur->pNext;//此时的pCur为删除的前一个节点
   m--;
  }
  m = i;//恢复m以便下一次循环
  pDel = pCur->pNext;//标记删除节点
  pCur->pNext = pDel->pNext;//将删除节点前一个的pNext指向删除节点的后一个
  pCur = pCur->pNext;//将pCur后移一位重新开始
  DestroyNode(&pDel);
 }
 return pCur;
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<Windows.h>
#include"SList.h"
void test()
{
 Node* pNode;
 IntiSList(&pNode);
 Node*pos_a=PushBackSList(&pNode, 'a');
 PushBackSList(&pNode, 'b');
 PushBackSList(&pNode, 'c');
 PushBackSList(&pNode, 'd');
 PushBackSList(&pNode, 'e');
 Node*pos_f=PushBackSList(&pNode, 'f');
 pos_f->pNext = pos_a;//将点f指向a
 JosephCycle(&pNode, 0, 3);
}
int main()
{
 test();
 system("pause");
 return 0;
}

以上大概就是如何实现约瑟夫环。


























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值