标签:
循环链表时另一种形式的链式存储结构,把单链表中指向最后一个结点的指针指向单链表的表头结点,就形成了一个循环链表。循环链表无论从链表中的任意出发点出发均可找到表中的其他结点。
约瑟夫问题是犹太历史学家约瑟夫的一个故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
用循环链表来实现约瑟夫问题是一个很好的选择,第一,链表插入和删除元素的操作非常简单,第二,循环链表时一个环,可以持续进行计数杀人。然后我就花了一整天的时间来搞循环链表和约瑟夫问题。
头文件:(CirLinkList.h)
//CirLinkList循环链表 #ifndef CIRLINKLIST_H_ #define CIRLINKLIST_H_ #include <iostream> using std::cout; using std::endl; template<typename T> struct Node { T data; Node<T> *next; //构造函数 Node(); Node(T item, Node<T> *link=NULL); }; template <typename T> Node<T>::Node() { next=NULL; } template<typename T> Node<T>::Node(T item, Node<T> *link=NULL) { data=item; next=link; } template <typename T> class SimpleCirLinkList { protected: Node<T> *head; void Init(); public: Node<T> *GetElemPtr(int position) const; SimpleCirLinkList();//构造函数 virtual ~SimpleCirLinkList();//析构函数 bool IsEmpty(); int Length() const; void Clear(); void GetElem(int position, T &e); SimpleCirLinkList<T> &SetElem(int position, const T e); SimpleCirLinkList<T> &DeleteElem(int position, T &e); SimpleCirLinkList<T> &DeleteNode(Node<T> *tempPtr); SimpleCirLinkList<T> &InsertElem(int position, const T e); SimpleCirLinkList(const SimpleCirLinkList<T> ©); SimpleCirLinkList<T> &operator =(const SimpleCirLinkList<T> ©); }; //初始化 template<typename T> void SimpleCirLinkList<T>::Init() { head=new Node<T>; head->next=head; } template<typename T> Node<T> *SimpleCirLinkList<T>::GetElemPtr(int position) const { int curPosition=1; Node<T> *tempPtr=head->next; if(position==0) { return head; } while(tempPtr->next!=head && curPosition<position) { tempPtr=tempPtr->next; ++curPosition; } if(tempPtr!=head && curPosition==position) { return tempPtr; } else { return NULL; } } //构造函数 template<typename T> SimpleCirLinkList<T>::SimpleCirLinkList() { Init(); } template <typename T> SimpleCirLinkList<T>::~SimpleCirLinkList() //析构函数 { Clear(); delete head; } template <typename T> int SimpleCirLinkList<T>::Length() const { int count=0; Node<T> *tempPtr; for(tempPtr=head->next; tempPtr!=head; tempPtr=tempPtr->next) { ++count; } return count; } template <typename T> bool SimpleCirLinkList<T>::IsEmpty() { if(head->next==head) { return true; } else { return false; } } template <typename T> void SimpleCirLinkList<T>::Clear() { T temp; while(Length()>0) { DeleteElem(1,temp); } } template <typename T> void SimpleCirLinkList<T>::GetElem(int position, T &e) { Node<T> *tempPtr; if(position<1 || position>Length()) { cout<<"获取元素时超出范围!"<<endl; } else { tempPtr=GetElemPtr(position); e=tempPtr->data; } } template <typename T> SimpleCirLinkList<T> &SimpleCirLinkList<T>::SetElem(int position, const T e) { Node<T> *tempPtr; if(position<1 || position>Length()) { cout<<"获取元素时超出范围!"<<endl; } else { tempPtr=GetElemPtr(position); tempPtr->data=e; } return *this; } template <typename T> SimpleCirLinkList<T> &SimpleCirLinkList<T>::DeleteElem(int position, T &e) { Node<T> *tempPtr; Node<T> *dePtr; if(position<1 || position>Length()) { cout<<"获取元素时超出范围!"<<endl; } else { tempPtr=GetElemPtr(position-1); Node<T> *newPtr=tempPtr->next; dePtr=newPtr->next; e=newPtr->data; tempPtr->next=dePtr; delete newPtr; } return *this; } template<typename T> SimpleCirLinkList<T> &SimpleCirLinkList<T>::DeleteNode(Node<T> *tempPtr) { Node<T> *newPtr=head;//=GetElemPtr(tempPtr->data-1); while(newPtr->next!=tempPtr) { newPtr=newPtr->next; } newPtr->next=tempPtr->next; delete tempPtr; return *this; } template <typename T> SimpleCirLinkList<T> &SimpleCirLinkList<T>::InsertElem(int position, const T e) { if(position<1 || position>(Length()+1)) { cout<<"获取元素时超出范围!"<<endl; } else { Node<T> *tempPtr; Node<T> *newPtr=new Node<T>; newPtr->data=e; tempPtr=GetElemPtr(position-1); newPtr->next=tempPtr->next; tempPtr->next=newPtr; } return *this; } template <typename T> SimpleCirLinkList<T>::SimpleCirLinkList(const SimpleCirLinkList<T> ©) { //构造函数拷贝类参数必须为const的引用 int copyLength=copy.Length(); Init(); Node<T> *tempPtr=head->next; for(int curPosition=1; curPosition<=copyLength; curPosition++) { tempPtr=copy.GetElemPtr(curPosition); InsertElem(curPosition,tempPtr->data); } } template <typename T> SimpleCirLinkList<T> &SimpleCirLinkList<T>::operator =(const SimpleCirLinkList<T> ©) { if(copy!=this) { int copyLength=copy.Length(); Init(); Node<T> *tempPtr=head->next; for(int curPosition=1; curPosition<=copyLength; curPosition++) { tempPtr=copy.GetElemPtr(curPosition); InsertElem(curPosition,tempPtr->data); } } return *this; } template <typename T> std::ostream &operator <<(std::ostream &os, SimpleCirLinkList<T> &CirLinkList) { T e; for(int curPosition=1; curPosition<=CirLinkList.Length(); curPosition++) { CirLinkList.GetElem(curPosition,e); cout<<e<<" "; } return os; } #endif
源文件:(CirLinkList.cpp)
// CirLinkList.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "CirLinkList.h" #include <iostream> using namespace std; //n为共有多少人,m为数到几自杀。(41,3) void Josephus(int n, int m) { SimpleCirLinkList<int> CirLink; for(int i=1; i<=n; i++) { CirLink.InsertElem(i,i); } cout<<"约瑟夫链表为:"<<CirLink<<endl; Node<int> *deadmanPtr; Node<int> *tempPtr=CirLink.GetElemPtr(1); int e,s; cout<<"杀人顺序为:"; for(int i=1; i<=n; i++) { for(int j=1; j<=2; j++) { if(tempPtr==CirLink.GetElemPtr(0)) { tempPtr=tempPtr->next; } tempPtr=tempPtr->next; if(tempPtr==CirLink.GetElemPtr(0)) { tempPtr=tempPtr->next; } } e=tempPtr->data; cout<<e<<" "; deadmanPtr=tempPtr->next; CirLink.DeleteNode(tempPtr); tempPtr=deadmanPtr; /*CirLink.DeleteElem(e,s);*/ } cout<<endl; } int _tmain(int argc, _TCHAR* argv[]) { SimpleCirLinkList<int> CirLinkList; cout<<"链表的长度为:"<<CirLinkList.Length()<<endl; cout<<"链表是否为空? "; if(CirLinkList.IsEmpty()==1) { cout<<"Yes!"<<endl; } else { cout<<"No!"<<endl; } //CirLinkList.InsertElem(0,1); CirLinkList.InsertElem(1,2); CirLinkList.InsertElem(2,3).InsertElem(3,4).InsertElem(4,5).InsertElem(5,6); cout<<"链表的长度为:"<<CirLinkList.Length()<<endl; cout<<"链表是否为空? "; if(CirLinkList.IsEmpty()==1) { cout<<"Yes!"<<endl; } else { cout<<"No!"<<endl; } cout<<"循环链表为:"<<CirLinkList<<endl; //复制链表 //SimpleLinkList<int> copy(LinkList); SimpleCirLinkList<int> copy=CirLinkList; copy.InsertElem(2,0).InsertElem(3,0); cout<<"链表的长度为:"<<copy.Length()<<endl; cout<<"链表是否为空? "; if(copy.IsEmpty()==1) { cout<<"Yes!"<<endl; } else { cout<<"No!"<<endl; } cout<<"循环链表为:"<<copy<<endl; cout<<"设置值之后:"<<endl; copy.SetElem(1,100); cout<<"循环链表为:"<<copy<<endl; //清除链表 cout<<"清空链表"<<endl; copy.Clear(); cout<<"链表的长度为:"<<copy.Length()<<endl; cout<<"链表是否为空? "; if(copy.IsEmpty()==1) { cout<<"Yes!"<<endl; } else { cout<<"No!"<<endl; } Josephus(41, 3); system("pause"); return 0; }结果:
标签:
原文地址:http://blog.csdn.net/jiang111_111shan/article/details/45894107