约瑟夫环

描述:

N个人坐在一个圆桌,编号从1到N;

从第K个人开始,从1开始报数,报到M的人离座。

下一个接着从1开始报数,依此类推,直到最后一个离席。


分析一:

打印整个离席的过程

实现一:

使用循环链表,从K个开始遍历M个节点,删除节点;

接着遍历M,删除节点;

依此类推... ...

直到最后一个节点

时间复杂度一:

O(N * M)

Example1:

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>

typedef struct tagCycleLinkNode
{
	struct tagCycleLinkNode *pstNext;
	int iNum;
}CYCLE_LINK_NODE_S;

#define ERROR_SUCCESS 0
#define ERROR_FAILED 1

#define CYCLE_LINK_HEAD_INIT(name) {&(name), 0}

#define CYCLE_LINK_HEAD(name) \
	CYCLE_LINK_NODE_S stCycleHead = CYCLE_LINK_HEAD_INIT(name)


static inline void _CYCLE_link_Add(CYCLE_LINK_NODE_S *pstNew, CYCLE_LINK_NODE_S *pstPre, 
				   CYCLE_LINK_NODE_S *pstNext)
{
	assert(pstNew != NULL);
	assert(pstPre != NULL);
	assert(pstNext != NULL);

	pstNew->pstNext = pstNext;
	pstPre->pstNext = pstNew;
}

static inline void CYCLE_link_Add(CYCLE_LINK_NODE_S *pstHead, CYCLE_LINK_NODE_S *pstAddNode)
{
	assert(pstHead != NULL);
	assert(pstAddNode != NULL);

	/*
	manual assurance the link
	pstAddNode->pstNext = pstHead->pstNext;
	pstHead->pstNext = pstAddNode;
	*/
	_CYCLE_link_Add(pstAddNode, pstHead, pstHead->pstNext);
}

static inline void _CYCLE_link_Del(CYCLE_LINK_NODE_S *pstPre, CYCLE_LINK_NODE_S *pstNext)
{
	assert(pstPre != NULL);
	assert(pstNext != NULL);
	
	pstPre->pstNext = pstNext;
}


int CYCLE_link_Init(CYCLE_LINK_NODE_S *pstHead, int iCount)
{
	int i = 0; 
	int iRet = ERROR_SUCCESS;
	CYCLE_LINK_NODE_S *pstCurNode = NULL;

	assert(pstHead != NULL);

	for (i = 0; i < iCount; i++) 
	{
		pstCurNode = (CYCLE_LINK_NODE_S *)malloc(sizeof(CYCLE_LINK_NODE_S));
		if (pstCurNode != NULL)
		{
			memset(pstCurNode, 0, sizeof(CYCLE_LINK_NODE_S));
			pstCurNode->iNum = i + 1;
			CYCLE_link_Add(pstHead, pstCurNode);
		}
		else
		{
			iRet = ERROR_FAILED;
			break;
		}
	}	

	return iRet;
}

void CYCLE_link_DelWithValue(CYCLE_LINK_NODE_S *pstHead, int iNum)
{
	CYCLE_LINK_NODE_S *pstCurNode = NULL;
	CYCLE_LINK_NODE_S *pstPreNode = NULL;

	assert(pstHead != NULL);
	
	//printf("pre del num: %d \r\n", iNum);
	pstPreNode = pstHead;	
	pstCurNode = pstHead->pstNext;
	while (pstCurNode != pstHead)
	{
		if (iNum == pstCurNode->iNum)
		{
			printf("del num:%d \r\n", pstCurNode->iNum);
			_CYCLE_link_Del(pstPreNode, pstCurNode->pstNext);
			break;
		}	
		pstPreNode = pstCurNode;
		pstCurNode = pstCurNode->pstNext;
	}

	return;
}

CYCLE_LINK_NODE_S *CYCLE_link_SkipCount(CYCLE_LINK_NODE_S *pstHead, CYCLE_LINK_NODE_S *pstStartNode,
					int iNum)
{
	int iCount = 0;
	CYCLE_LINK_NODE_S *pstCurNode = NULL;
	CYCLE_LINK_NODE_S *pstSkipNode = NULL;

	assert(pstStartNode != NULL);
	
	printf("Skip list:");
	pstCurNode = pstStartNode;
	while (pstCurNode != NULL)
	{
		if (pstCurNode != pstHead)
		{
			printf("%d ", pstCurNode->iNum);
			iCount++;
		}
		if(iCount == iNum)
		{
			pstSkipNode = pstCurNode;
			break;
		}
		pstCurNode = pstCurNode->pstNext;
	}	
	printf("\r\n");
	return pstSkipNode;
}

void CYCLE_link_Display(CYCLE_LINK_NODE_S *pstHead)
{
	CYCLE_LINK_NODE_S *pstCurNode = NULL;
	
	assert(pstHead != NULL);
	
	if (pstHead->pstNext == pstHead)
	{
		printf("empty list.\r\n");
		return;
	}
	
	pstCurNode = pstHead->pstNext;
	while (pstCurNode != pstHead)
	{
		printf("%d ", pstCurNode->iNum);
		pstCurNode = pstCurNode->pstNext;
	}
	printf("\r\n");
	
	return;
}

int JPH_CycleRun(CYCLE_LINK_NODE_S *pstHead, CYCLE_LINK_NODE_S *pstStartNode, int iRunCount)
{
	int iCount = 0;
	CYCLE_LINK_NODE_S *pstCurNode = NULL;
	CYCLE_LINK_NODE_S *pstSkipNode = NULL;

	assert(pstHead != NULL);
	assert(pstStartNode != NULL);
	
	pstCurNode = pstStartNode;
	while (pstHead->pstNext != pstHead)
	{
		pstSkipNode = CYCLE_link_SkipCount(pstHead, pstCurNode, iRunCount);
		pstCurNode = pstSkipNode->pstNext;
		CYCLE_link_DelWithValue(pstHead, pstSkipNode->iNum);
		//CYCLE_link_Display(pstHead);	
	}	
	
	return 0;
}

int main()
{
	
	CYCLE_LINK_HEAD(stCycleHead);
	CYCLE_LINK_NODE_S *pstStartNode = NULL;
	
	CYCLE_link_Init(&stCycleHead, 10);
	
	CYCLE_link_Display(&stCycleHead);	

	pstStartNode = CYCLE_link_SkipCount(&stCycleHead, &stCycleHead, 5);
	
	CYCLE_link_Display(pstStartNode);	

	JPH_CycleRun(&stCycleHead, pstStartNode, 4);
	
	
	return 0;
}

结果一:

10 9 8 7 6 5 4 3 2 1
Skip list:10 9 8 7 6
5 4 3 2 1 0 10 9 8 7
Skip list:6 5 4 3
del num:3
Skip list:2 1 10 9
del num:9
Skip list:8 7 6 5
del num:5
Skip list:4 2 1 10
del num:10
Skip list:8 7 6 4
del num:4
Skip list:2 1 8 7
del num:7
Skip list:6 2 1 8
del num:8
Skip list:6 2 1 6
del num:6
Skip list:2 1 2 1
del num:1
Skip list:2 2 2 2
del num:2



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值