![]() |
#2
GLOCET2008-06-21 16:58
发一个给你参考一下,跟你要求的一样,设计方式也一样.
入门的东西 [quote] //CNode.h template<typename T> class CNode { private: CNode<T> *next; //指向下一节点循环指针 public: T data; CNode(); //construct CNode(const T & item); //更新表的方法 void InsertAfter(CNode<T> *p); CNode<T>*DeleteAfter(); //保存下一节点的指针 CNode<T> *NextNode()const; }; [\quote] [quote] //CNode.cpp #include "CNode.h" template<typename T> CNode<T>::CNode() { next=this; //下一节点为结点本身 } //产生空表并初始化数据的构造函数 template<typename T> CNode<T>::CNode(const T& item) { //将结点指向自身并初始化数据 next=this; data=item; } //在当前结点之前插入结点P template<typename T> void CNode<T>::InsertAfter(CNode<T> * p) { //p指向当前结点的后继结点,当前结点指向P p->next=next; next=p; } //删除当前结点之后的结点,并返回指向其的指针 template<typename T> CNode<T>*CNode<T>::DeleteAfter() { //保存指向被删除结点的指针 CNode<T> *tempPtr=next; //若next==this ,表明没有其他结点,返回NULL if(next==this) return NULL; //当前结点指向tempPtr的后继结点。 next=tempPtr->next; //返回指向被删除结点的指针 return tempPtr; } template<typename T> CNode<T>* CNode<T>::NextNode()const { return next; } [\quote] [quote] #include<iostream> #include "CNode.h" using namespace std; void CreateList(CNode<int> *header,int n) { //开始往头结点插入 CNode<int>*currPtr=header,*newNodePtr; int i; //建立起N元循环链表 for(i=1;i<=n;i++) { //用数据值i申请结空间 newNodePtr=new CNode<int>( i); //往表尾插入结点并将currPtr指针前移到表尾 currPtr->InsertAfter(newNodePtr); currPtr=newNodePtr; } } //对给定的n 元循环链表,通过每次便使第M个人出局直到最后一个末解决Josephus问题 void Josephus(CNode<int> *list,int n,int m) { CNode<int>*prevPtr=list,*currPtr=list->NextNode(); CNode<int> *deleteNodePtr; //删除表中结点只到最后一个 for(int i=0;i<n-1;i++) { //从CURRPTR指向的当前客人开始数人,即指针前移m-1次 for(int j=0;j<m-1;j++) { //前移指针 prevPtr=currPtr; currPtr=currPtr->NextNode(); //若CURRPTR指向表头,再移一次指针 if(currPtr==list) { prevPtr=currPtr; currPtr=currPtr->NextNode(); } } cout<<"Delete person "<<currPtr->data <<endl; //记录被删除的结点,并前移currPtr指针 deleteNodePtr=currPtr; currPtr=currPtr->NextNode(); //从表中删除该结点 prevPtr->DeleteAfter(); delete deleteNodePtr; //若CURRPTR为头指针,则再移一次 if(currPtr==list) { prevPtr=currPtr; currPtr=currPtr->NextNode(); } } cout<<endl<<"Person"<<currPtr->data<<"Wins the cruise."<<endl; //删除表中最后一个结点 deleteNodePtr=list->DeleteAfter(); delete deleteNodePtr; } int main() { CNode<int> list; int n,m; //n为表中人数,M为循环选择因子 cin>>n; CreateList(&list,n); cin>>m; cout<<"Generated the member"<<m<<endl; Josephus(&list,n,m); system("pause"); return 0; } [\quote] |
约瑟夫环问题:
[问题描述]
约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。
[基本要求]
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
[测试数据]
m的初值为20;密码:3,1,7,2,4,8,4(正确的结果应为6,1,4,7,2,3,5)。
[实现提示]
程序运行后首先要求用户指定初始报数上限值,然后读取各人的密码。设n≤30。
自己写了一段程序代码,但总想不出具体的操作函数,程序文档包含在附件内,大家帮帮忙吧,提前谢谢各位!!!
如果有可能,请把解决方案发到邮箱tscott@,谢谢!
[[it] 本帖最后由 wiki 于 2008-6-19 23:09 编辑 [/it]]