链表— —循环链表的算法实现

Joseph问题


有 10 个小朋友按编号顺序 1,2,。。。,10 顺时针方向围成一圈。从 1 号开始顺时针方向 1,2,。。。,9 报数,凡报数 9 者出列(显然,第一个出圈为编号 9 者)。

最后一个出圈者的编号是多少?第 5 个出圈者的编号是多少?

 

#include<iostream>

#include<string>

#include<stdlib.h> using namespace std;

typedef struct _LinkNode {

int data; //结点的数据域

struct _LinkNode *next; //结点的指针域

}LinkNode, LinkList; //LinkList为指向结构体LNode的指针类型

void LinkPrint(LinkList *L);

bool InitList(LinkList* &L)//构造一个空的循环链表L

{

L=new LinkNode; //生成新结点作为头结点,用头指针L指向头结点

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;

//找到最后一个节点

last = L;

while(last->next!=L) last=last->next;

//新的节点链接到最尾部

node->next = L; last->next = node; return true;

}

bool Joseph(LinkList* &L, int interval)

{

//在带头结点的循环链表L中,每个interval 个间隔循环删除节点

LinkList *p, *q;

int j = 0, i = 0;

int times = 0, num = 0;

p=L;

if(!L || p->next == L) { cout<<"链表为空!"<<endl;

return false;

}

if(interval<1){

cout<<"报数淘汰口令不能小于1!"<<endl;

return false;

}

do{ i += interval;

while((p->next)) //查找第i个结点,p指向该结点的上一个节点

{ if(p->next!=L) j++; if(j>=i) break; p=p->next;

}

times++;

/*if (!(p->next)||(j>i))//当i>n或i<1时,删除位置不合理 return false;*/

q=p->next; //临时保存被删结点的地址以备释放空间 num = q->data;

if(times==5) cout<<"第5个出圈的编号是:"<<num<<endl;11 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->next!=L);//链表不为空,继续报数

cout<<"最后一个出圈的编号是:"<<num<<endl; return true;

}

void LinkPrint(LinkList *L) //循环链表的输出

{

LinkList *p;

if(!L || L==L->next){ cout<<"链表为空!"<<endl; return ;

} p=L->next;

while (p!=L)

{ cout <<p->data <<"\t";

p=p->next;

}

cout<<endl;

}

int main(){ int i, x;

LinkList *L;

LinkNode *s;

//1. 初始化一个空的循环链表

if (InitList(L)){

cout << "初始化一个空的循环链表!\n";

//2. 创建循环链表(尾插法)

std::cout <<"尾插法创建循环链表, 插入10个元素..."11 <<endl; i = 0;

while((++i)<=10)

{

s=new LinkNode;//生成新结点 s->data=i; //输入元素值赋给新结点的数据域 s->next=NULL;

if(ListInsert_back(L, s)){ cout<<"插入成功!"<<endl;

}else { cout<<"插入失败!"<<endl;

}

}

cout << "尾插法创建循环链表输出结果:\n";

LinkPrint(L);

//3. 解答约瑟夫问题

Joseph(L, 9); system("pause"); return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的鱼-blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值