数据结构- 环形链表
前段时间跟着尚硅谷的视频学习,自己截图做了一些学习笔记,现在简单整理出来供大家参考,同时也方便自己日后复习查询,如果有存在疏漏,欢迎大家批评指正。文末将会附上视频链接。
单向环形链表
结构示意图
创建单向环形链表:
//环形链表的构建
public void addBoy(int nums){
//nums做一个数据校验
if (nums <1){
System.out.println("nums的值不正确");
return;
}
Boy curBoy=null;//辅助指针,帮助构建环形链表
//使用for循环创建循环链表
for (int i=1;i<=nums;i++){
//根据编号,创建小孩节点
Boy boy=new Boy(i);
//如果是第一个小孩
if (i==1){
first = boy;
first.setNext(first);//构成环
curBoy=first;//让curBoy指向第一个小孩
}else {
curBoy.setNext(boy);
boy.setNext(first);
curBoy=boy;
}
}
}
显示环形链表:
//遍历环形链表
public void showBoy(){
//判断链表是否为空
if(first==null){
System.out.println("链表为空");
return;
}
//用辅助指针完成遍历
Boy curBoy=first;
while (true){
System.out.printf("小孩编号为%d \n",curBoy.getNo());
if (curBoy.getNext()==first){//遍历完成
break;
}
curBoy=curBoy.getNext();//curBoy后移
}
}
约瑟夫问题
设编号为1,2,3…n的n个人围坐一圈,约定编号为k(1≤k≤n)的人从1开始报数,数到m的那个人出列,他的下一位又从1开始报数,数到m的人又出列,依次类推,直到所有人出列为止,由此产生出一个出列编号的序列。
构建好环形链表后,进行出圈处理
//根据用户的输入,计算出小孩出圈的顺序
/*
* startNo -表示从第几个小孩开始数数
* countNum -表示数几下
* nums -表示最初有多少小孩在圈中
*/
public void countBoy(int startNo, int countNum, int nums) {
//先对数据进行校验
if (first == null || startNo < 1 || startNo > nums) {
System.out.println("参数输入有误,请重新输入");
return;
}
//创建辅助接点,帮助小孩出圈
Boy helper = first;
//创建辅助指针helper,事先应该指向环形链表的最后节点
while (true){
if (helper.getNext()==first){
break;
}
helper=helper.getNext();
}
//小孩报数前,先让first和helper 移动k-1次
for (int j=0;j<startNo-1;j++){
first=first.getNext();
helper=helper.getNext();
}
//当小孩报数时,让first和helper指针同时移动m-1次,然后出圈
//这是一个循环操作,直到圈中只有一个节点
while (true){
if (helper==first){//说明圈中只有一个节点
break;
}
//让first和helper指针同时移动m-1次,
for (int j=0;j<countNum-1;j++){
first=first.getNext();
helper=helper.getNext();
}
//这时first指向的节点,就是要出圈的节点
System.out.printf("小孩%d出圈\n",first.getNo());
//first节点出圈
first=first.getNext();
helper.setNext(first);
}
System.out.printf("最后留着圈中的小孩%d\n",first.getNo());
}
在此附上尚硅谷的教学视频:
【尚硅谷】数据结构与算法(Java数据结构与算法)