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

来源:互联网 发布:苹果序列号查询软件 编辑:程序博客网 时间:2024/06/11 05:31
  

约瑟夫环

是一个数学的应用问题:

已知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;}


      程序运行结果如下所示:


原创粉丝点击