循环链表和约瑟夫环

来源:互联网 发布:专业的vb振动电机 编辑:程序博客网 时间:2024/05/01 16:48

循环链表时另一种形式的链式存储结构,把单链表中指向最后一个结点的指针指向单链表的表头结点,就形成了一个循环链表。循环链表无论从链表中的任意出发点出发均可找到表中的其他结点。

约瑟夫问题是犹太历史学家约瑟夫的一个故事:在罗马人占领乔塔帕特后,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> &copy);SimpleCirLinkList<T> &operator =(const SimpleCirLinkList<T> &copy);};//初始化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> &copy){//构造函数拷贝类参数必须为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> &copy){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;}
结果:


1 0
原创粉丝点击