描述:
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