【单链表经典面试题解析四】用单链表实现约瑟夫环

  

约瑟夫环

是一个数学的应用问题:

已知n个人(以编1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。

这个就是约瑟夫环问题的实际场景,有一种是要通过输入n,m,k三个正整数,来求出列的序列。这个问题采用的是典型的循环链表的数据结构,就是将一个链表的尾元素指针指向队首元素。

那么如何用单链表实现约瑟夫环呢?

第一步建立一个具有n个链结点,无头结点的循环链表(假设每次都从头结点开始报数)

《【单链表经典面试题解析四】用单链表实现约瑟夫环》

第二步,开始报数

《【单链表经典面试题解析四】用单链表实现约瑟夫环》


 第三步,报到m的人出局,删除节点(删除节点之后要注意使用free函数,释放该空间)。

《【单链表经典面试题解析四】用单链表实现约瑟夫环》


第四步,当循环结束的时候,一定记得要解环,令最后一个节点的下一个指针域指向空。


    最后,程序如下所示:

#define _CRT_SECURE_NO_WARNINGS 1  
#include<stdio.h>
#include<Windows.h>
#include<stdio.h>
#include<assert.h>
#include<malloc.h>

typedef int DataType;
typedef struct Node
{
	DataType _data;
	struct Node * _pNext;
}*pNode;

//初始化单链表
void InitList(pNode* pHead)
{
	assert(pHead);
	*pHead = NULL;
}

//创建一个新节点
pNode BuyNode(DataType data)
{
	pNode pNewNode = (pNode)malloc(sizeof(struct Node));
	if(NULL == pNewNode)
	{
		assert(0);
		return NULL;
	}
	pNewNode->_data = data;
	pNewNode->_pNext = NULL;
	return pNewNode;
}

//头插
void PushBack(pNode* pHead,DataType _data)
{
	assert(pHead);
	if(NULL == *pHead)
	{
		*pHead = BuyNode(_data);
	}
	else
	{
		pNode pTailNode = *pHead;
		while(pTailNode->_pNext)
		{
			pTailNode = pTailNode->_pNext;
		}
		pTailNode->_pNext = BuyNode(_data);
	}
}

//顺序打印单链表
void PrintList(pNode pHead)
{
	pNode pCur = pHead;
	while(pCur)
	{
		printf("%d--->",pCur->_data);
		pCur = pCur->_pNext;
	}
	printf("NULL\n");
}
// 单链表实现约瑟夫环 
pNode JosephCircle(pNode pHead, int M)
{
	pNode pCur;
	pNode pDel;
	int count = 0;
	if(NULL == pHead)
		return NULL;
	pCur = pHead;
	//构环
	while(pCur->_pNext)
	{
		pCur=pCur->_pNext;
	}
	pCur->_pNext = pHead;
	pCur = pHead;
	while(pCur != pCur->_pNext)
	{
		//报数
	    count = M;
	    while(--count)
	    {
		    pCur = pCur->_pNext;
	    }
	    //删节点
	    pDel = pCur->_pNext;
	    pCur->_data = pDel->_data;
	    pCur->_pNext = pDel->_pNext;
	    free(pDel);
	}
	//解环
	pCur->_pNext = NULL;
	return pCur;
}

//测试
void test()
{
	pNode pHead;
	pNode pJosephNode = NULL;//最后存活的节点
	DataType m;//出局密码
	InitList(&pHead);
	PushBack(&pHead,1);
	PushBack(&pHead,2);
	PushBack(&pHead,3);
	PushBack(&pHead,4);
	PushBack(&pHead,5);
	PushBack(&pHead,6);
	printf("请输入出局密码:>");
	scanf("%d",&m);
	printf("原链表为:>");
	PrintList(pHead);
	pJosephNode = JosephCircle(pHead,m);
	printf("最后存活的为:>");
	PrintList(pJosephNode);
}
int main(){
	test();
	system("pause");
	return 0;
}


     
 
程序运行结果如下所示:

《【单链表经典面试题解析四】用单链表实现约瑟夫环》

    原文作者:约瑟夫环问题
    原文地址: https://blog.csdn.net/sofia_m/article/details/78278372
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞