C++不带头结点的单循环链表解决约瑟夫环问题

重新把殷人昆的C++数据结构(2版)重新走一遍,发现以前的基础太差,这个简单的基础的东西都搞了好久才搞出来啊~~~~~

言归正题:

首先建立要力一个CircList.h头文件代码如下:

//不带头结点的单循环链表

#ifndef CIRCLIST_H
#define CIRCLIST_H

#ifndef CH_H
#define CH_H
#include 
#include
using namespace std;
#endif

template
struct CircLinkNode
{
T data;
CircLinkNode *link;
CircLinkNode(CircLinkNode* next = NULL) :link(next){ }
CircLinkNode(T d, CircLinkNode* next = NULL) :data(d), link(next){ }
};


template
class circList
{
public:
circList();
circList(const T& x);
circList(circList& L);
~circList();
int Length()const;
void makeEmpty();
bool IsEmpty(){ return first ->link==first ? true : false; }
/*bool IsFull(){ return last->link == first ? true : false; }*/
CircLinkNode *getHead(){ return first; }
bool Insert(int i, T& x);
bool Remove(int i, T& x);
bool setData(int i, T& x);
bool getData(int i, T& x);
CircLinkNode* Search(T x);
CircLinkNode* Locate(int i);
void output();
void inputFront(T endTag);
void inputRear(T endTag);
private:
CircLinkNode *first, *last;
};
//


template
circList::circList()
{
first = last = NULL;
}


template
circList::circList(const T& x)
{
first = last = NULL;
}


template
circList::circList(circList& L)
{
T value;
CircLinkNode* srcptr, *destptr;
srcptr = L.first;
first = destptr = new CircLinkNode(srcptr->data);
while (srcptr!=L.first)
{
value = srcptr->link->data;
destptr->link = new CircLinkNode(value);
destptr = destptr->link;
srcptr = srcptr->link;

}
last = destptr;
last->link = first;
}


template
circList::~circList()
{
makeEmpty();
}


template
int circList::Length()const
{
int count=0;
CircLinkNode* p = first;
while (p->link!=first)
{
p=p->link;
count++;
}
return ++count;
}


template
void circList::makeEmpty()
{
CircLinkNode* del;
while (first!=NULL)
{
del = first;
first = first->link;
delete del;
}
last = NULL;
}


template
bool circList::Insert(int i, T& x)
{
//向后插入
if (i<0)
{
return false;
}
CircLinkNode *current = Locate(i);
if (current==NULL)
{
return false;
}
CircLinkNode *newNode = new CircLinkNode(x);
if (newNode==NULL)
{
cerr << "内存分配失败!" << endl;
}
if (current!=last)
{
newNode->link = current->link;
current->link = newNode;
return true;
}
else
{
newNode->link = first;
last->link = newNode;
last = last->link;


}

}


template
bool circList::Remove(int i, T& x)
{
CircLinkNode *current = Locate(i);
if (current==NULL)
{
return false;
}
else if (current == first)
{
first = first->link;
x = current->data;
delete current;

}
else if (current==last)
{
CircLinkNode* temp = Locate(i - 1);
temp->link = first;
last = temp;
last->link = first;
delete current;

}
else
{
CircLinkNode* temp = Locate(i - 1);
temp->link = current->link;
delete current;


}
return true;

}


template
bool circList::setData(int i, T& x)
{
if (i<0)
{
return false;
}
CircLinkNode *current = Locate(i);
if (!current)
{
return false;
}
current->data = x;
return true;
}


template
bool circList::getData(int i,T& x)
{
if (i < 0)
{
return false;
}
CircLinkNode *current = Locate(i);
if (!current)
{
return false;
}
x = current->data;
return true;
}


template
//CircLinkNode* circList::Search(T x)const
CircLinkNode* circList::Search(T x)
{
CircLinkNode*  current=first;
while (current!=NULL&¤t->link!=first)
{
if (current->data==x)
{
break;
}
else
{
current = current->link;
}
}
return current;
}


template
CircLinkNode* circList::Locate(int i)
{
if (i < 0)
{
return NULL;
}
if (i == 0)
{
return first;
}
CircLinkNode* current = first;
int k = 1;
while (current->link != first && k < i)
{
current = current->link;
k++;
}
return current;
}


template
void circList::inputFront(T endTag)
{
CircLinkNode* newNode;
T val;
makeEmpty();
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode(val);
if (newNode == NULL)
{
cerr << "内存分配错误!" << endl;
exit(1);
}
last = first = newNode;
first->link = last;
last->link = first;
while (val != endTag)
{
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode(val);
newNode->link = first;
first = newNode;
last->link = first;//必须把last的指针域更新下,它是不会同步更新的。
}
else
{
break;
}
}
}

}


template
void circList::inputRear(T endTag)
{
CircLinkNode* newNode,*current;
T val;
makeEmpty();
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode(val);
first = last = current= newNode;
first->link = last;
last->link = first;
while (val!=endTag)
{
cin >> val;
if (val!=endTag)
{
newNode = new CircLinkNode(val);
current->link = newNode;
last=current = newNode;
last->link = first;//必须把last的指针域更新下,它是不会同步更新的。
}
else
{
break;
}
}
}




}


template
void circList::output()
{
int i = 0;
CircLinkNode* current = first;
while (current!=NULL&¤t->link!=first)
{
cout << "#"<< i<<":" << current->data << endl;
current = current->link;
i++;
}
cout << "#" << i << ":" << current->data << endl;
}


#endif
之后就是测试自己的写的代码和写出约瑟夫环的结果了:
main.cpp如下:

#include "CircList.h"

template
void josephus(circList& Js, int n, int m)
{
CircLinkNode* p = Js.Locate(1), *pre = NULL;
for (int i = 1; i < n ;i++)
{
for (int j = 1; j < m; j++)
{
pre = p;
p = p->link;
}
cout << "出列的第"<data << endl;
pre->link = p->link;
delete p;
p = pre->link;
}
cout << "最后的幸运者:" << p->data << endl;
}

main.cpp代码如下:


void main()
{
//circList c1,c2;
///*for (int i = 0; i < 5;i++)
//{
// cl.Insert(i, i);
//}*/
//cout << "前插法:" << endl;
//c1.inputFront(-1);
//c1.output();
///*cout << "insert函数插入一个数:"< clist;
int i, n, m;
cout << "建立循环链表:" << endl;
clist.inputRear(-1);
cout << "输入游戏的人数和报数间隔:";
cin >> n >> m;
josephus(clist, n, m);


while (1)
{


}
}


注意: 血泪史,如果代码是模板类的话,不要把声明和定义分开放在头文件和源文件中,不然会有好多你意想不到的错误啊!!!!

截图效果如下:


C++不带头结点的单循环链表解决约瑟夫环问题_第1张图片

你可能感兴趣的:(循环单链表,不带头结点,约瑟夫环)