循环链表以及约瑟夫问题的解决
#include <iostream>
using namespace std;
typedef struct _LinkNode{
int data; //数据域
struct _LinkNode *next;//指针域
}LinkNode,LinkList;
//初始化循环链表
bool initList(LinkList * &L){
L = new LinkNode;
if(!L) return false;
L->next = L;//使指针域的头节点指向自己
L->data = -1;
return true;
}
//尾插法
bool ListInsert_back(LinkList* &L,LinkNode* node){
LinkNode* last = NULL;
if(!L || !node) return false;
if(L == L->next) {//空的循环链表,头节点指向自己
node->next = L;
L->next = node;
}else{
last = L;
while(last->next != L){
last = last->next;//定位到最后一个节点
}
last->next = node;
node->next = L;
}
return true;
}
void LinkPrint(LinkList *L){
LinkList *p = NULL;
if(!L ||L == L->next){
cout<<"链表为空!"<<endl;
return ;
}
p = L->next;
while(p!=L){
cout<<p->data<<"\t";
p = p->next;
}
cout<<endl;
}
bool Joseph(LinkList* &L,int interval){
LinkNode *p,*q;
int i=0,j=0;
int times = 0;
int num = 0;
p = L;
if(!L || L == L->next){
cout<<"链表为空"<<endl;
return false;
}
if(interval < 1){
cout<<"淘汰口令不能小于1"<<endl;
return false;
}
do{
i+=interval;
//查找第i个节点,p指向该节点的上一个节点
while(p->next){
if(p->next !=L) j++;
if(j>=i) break;//考虑interval为1的情况
p=p->next;
}
times++;
q = p->next;
num = q->data;
if(num == 5) cout<<"第5个出圈的编号是"<<num<<endl;
printf("cur:%d last:%d next:%d\n",q->data,p->data,q->next->data);
p->next = q->next;
delete q;//释放被删除节点的空间
LinkPrint(L);
}while(L!=L->next);
cout<<"最后一个出圈的编号是:"<<num<<endl;
return true;
}
int main(void){
LinkList *L;
LinkNode *s;
int i = 0;
if(initList(L)){
cout<<"成功初始化一个空的循环链表!\n"<<endl;
}else{
exit(-1);
}
cout<<"尾插法创建循环链表,插入10个元素..."<<endl;
while(++i<=10){
s = new LinkNode;
s->data = i;
s->next = NULL;
if(ListInsert_back(L,s)){
cout<<"插入成功"<<endl;
}else{
cout<<"插入失败"<<endl;
}
}
cout<<"尾插法创建循环链表的结果"<<endl;
LinkPrint(L);
//解答约瑟夫问题
Joseph(L,9);
system("pause");
return 0;
}