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

简介: 链表— —循环链表的算法实现

Joseph问题


f272bcbf851147d996d61dc2e6d4ef3d.png


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

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

e5a3109ac0da44ff92779d4296e447b5.png

#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;
}


相关文章
|
1月前
|
算法
【链表】算法题(二) ----- 力扣/牛客
【链表】算法题(二) ----- 力扣/牛客
|
5月前
|
存储 算法 Go
算法学习:数组 vs 链表
算法学习:数组 vs 链表
65 0
|
5月前
|
存储 缓存 算法
数据结构和算法学习记录——总结顺序表和链表(双向带头循环链表)的优缺点、CPU高速缓存命中率
数据结构和算法学习记录——总结顺序表和链表(双向带头循环链表)的优缺点、CPU高速缓存命中率
49 0
|
5月前
|
算法
数据结构和算法学习记录——习题-移除链表元素
数据结构和算法学习记录——习题-移除链表元素
24 0
|
1月前
|
算法
【链表】算法题(一) ----- 力扣 / 牛客
【链表】算法题(一) ----- 力扣 / 牛客
|
3月前
|
存储 算法
【初阶数据结构篇】顺序表和链表算法题
此题可以先找到中间节点,然后把后半部分逆置,最近前后两部分一一比对,如果节点的值全部相同,则即为回文。
30 0
|
5月前
|
算法 Java
[Java·算法·中等] LeetCode21. 合并两个有序链表
[Java·算法·中等] LeetCode21. 合并两个有序链表
54 2
|
5月前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
56 2
|
5月前
|
算法 Java C语言
【经典算法】LeetCode25:K 个一组翻转链表(Java/C/Python3,Hard)
【经典算法】LeetCode25:K 个一组翻转链表(Java/C/Python3,Hard)
35 1
|
5月前
|
算法 安全 Java
【经典算法】LeetCode 21:合并两个有序链表Java/C/Python3实现含注释说明,Easy)
【经典算法】LeetCode 21:合并两个有序链表Java/C/Python3实现含注释说明,Easy)
37 1
下一篇
无影云桌面