什么是单向循环链表

单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是null,而是头节点(注意:不是头指针).

因此,单向循环链表的任何节点的下一部分都不存在NULL值。

由于单向循环链表的特性,它在处理一些环状数据的时候十分有效.大名鼎鼎的约瑟夫环问题就可以用循环单向链表求解,下面我们会有进一步的介绍。

由于单向循环链表和单向链表的差别真的不大,增添改查原理都相同。因此在这里我们不详细讲解,只提供源码。(如果你还是不理解的话,这里有单向链表的传送门)


源码实现(Java)

public class Node<Anytype> {
public Anytype data;
public Node<Anytype> next;
public Node(Anytype data,Node<Anytype> next){
this.data=data;
this.next=next;
}
} ------------------------------------ public class SingleLink<AnyType> { //首元节点
public Node<AnyType> first; //头指针
public Node<AnyType> head; //链表长度
int thesize; //初始化链表
public boolean initlist(){
thesize=0;
first=new Node<>(null,null);
head=new Node<>(null,first);
first.next=head;
return true;
} //判断链表是否为空
public boolean isEmpty(){
return thesize==0;
} //获取节点
public Node<AnyType> getNode(int i){
Node<AnyType> renode=head;
for(int j=-2;j<i;j++){
renode=renode.next;
}
return renode;
} //在末尾添加元素
public void add(AnyType a){
Node<AnyType> renode=new Node<>(a,null);
getNode(thesize-1).next=renode;
renode.next=first.next;
thesize++;
} //删除i位置节点,并返回删掉的数据
public AnyType remove(int i){
if(i==thesize-1){
AnyType a=getNode(thesize-1).data;
getNode(thesize-2).next=first.next;
return a;
}
Node<AnyType> prev=getNode(i-1);
AnyType a=prev.next.data;
prev.next=prev.next.next;
thesize--;
return a;
} public void remove2(Node<AnyType> n){ } //在i位置插入新节点
public void insert(int i,AnyType a){
Node<AnyType> prev=getNode(i-1);
Node<AnyType> renode=new Node<>(a,prev.next);
prev.next=renode;
thesize++;
} //获取i位置节点的数据
public AnyType get(int i){
return getNode(i).data;
} //为i位置元素重新赋值
public void set(int i,AnyType a){
getNode(i).data=a;
} //返回链表节点个数
public int length(){
return thesize;
} //清空链表
public void clear(){
initlist();
} //打印链表
public void print(){
for(int i=0;i<thesize;i++){
System.out.println(getNode(i).data);
}
} }

单向循环链表的应用----约瑟夫环问题

问题来历

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。

思路分析

首先所有的人是围城一圈的,而且需要循环很多圈才能够将所有人依次排除,而这非常适合刚刚完成的单向循环链表才解决,尾节点的下一个节点又重新拿到的头节点,刚刚和问题中的情况契合。

首先我们只要拿到链表的头节点,然后依次通过头节点的next指针往后拿到下一个节点,找到第3个移除链表,然后依次循环直到链表为空,移除的顺序就是我们需要的死亡顺序。

源码实现(此处的循环单向链表是上面我们实现的-SingleLink)
import java.util.Scanner;

public class JosephRing {
public static void main(String[] args){
int sum=0;
int space=0;
String s="";
System.out.println("输入环数和间隔");
Scanner sc=new Scanner(System.in);
sum=sc.nextInt();
space=sc.nextInt();
SingleLink<Integer> sl=new SingleLink<>();
sl.initlist();
//编号add进链表
for(int i=0;i<sum;i++){
sl.add(i+1);
}
Node<Integer> n=sl.first;
while(n.next!=n){
for(int i=1;i<space;i++){
n=n.next;
}
int a=n.next.data;
n.next=n.next.next;
s=s+a+",";
}
System.out.println(s);
}
}
/*
输入:41
3
输出:3,6,9,12,15,18,21,24,27,30,33,36,39,1,5,10,14,19,23,28,32,37,41,7,13,20,26,34,40,8,17,29,38,11,25,2,22,4,35,16,
*/

(java实现)单向循环链表的更多相关文章

  1. java实现单向循环链表

    链表图解 带头结点的链表: 不带头结点的链表: 区别 带头结点的链表容易代码实现 不带头结点的容易实现循环链表和双向链表 代码的实现 (增减 删除) 节点实现: public class node { ...

  2. Java 用单向循环链表实现 约瑟夫问题

    public class lianbiao2 { class Node{ Node next; int number; public Node getNext() { return next; } p ...

  3. 关于单向循环链表的约瑟夫问题(Java实现)

    关于单向循环链表的约瑟夫问题(Java实现) 最近在学习链表时,遇到单向循环链表中的约瑟夫问题.在构建循环链表的代码上,我有一点很不理解,遂记录下来. Josephu问题为: 设编号为1, 2,.. ...

  4. java与数据结构(4)---java实现双向循环链表

    线性表之链式存储结构双向循环链表 双向循环链表:每个结点包含了数据.直接前驱地址指针和直接后驱地址指针,头结点的直接前驱指向尾结点,尾结点的直接后驱指向头结点,头尾相连构成一个可正可反的圆环.可以形象 ...

  5. (java实现)双向循环链表

    什么是双向循环链表 在了解双向循环链表之前,如果对链表还没有一个清晰的概念,建议你看看单链表和单向循环链表,这有利于你更好的理解下面的内容.(废话有点多[逃] 相比单链表,双向循环链表是一个更加复杂的 ...

  6. 基于visual Studio2013解决算法导论之021单向循环链表

     题目 单向循环链表的操作 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> ...

  7. Python 单向循环链表

    操作 is_empty() 判断链表是否为空 length() 返回链表的长度 travel() 遍历 add(item) 在头部添加一个节点 append(item) 在尾部添加一个节点 inser ...

  8. 单向循环链表C语言实现

    我们都知道,单向链表最后指向为NULL,也就是为空,那单向循环链表就是不指向为NULL了,指向头节点,所以下面这个程序运行结果就是,你将会看到遍历链表的时候就是一个死循环,因为它不指向为NULL,也是 ...

  9. python中的单向循环链表实现

    引子 所谓单向循环链表,不过是在单向链表的基础上,如响尾蛇般将其首尾相连,也因此有诸多类似之处与务必留心之点.尤其是可能涉及到头尾节点的操作,不可疏忽. 对于诸多操所必须的遍历,这时的条件是什么?又应 ...

随机推荐

  1. Linux下串口配置初步探寻

    一.在struct termios结构体中,对串口进行基本配置(如波特率设置,校验位和停止位设置 等). (一): struct termios   //串口的设置主要是设置struct termio ...

  2. three.js实现球体地球城市模拟迁徙

    概况如下:1.SphereGeometry实现自转的地球:2.THREE.ImageUtils.loadTexture加载地图贴图材质:3.THREE.Math.degToRad,Math.sin,M ...

  3. manacher --- 暂 旧版本

    #include<bits/stdc++.h> using namespace std; ; ]; int n; ]; void manacher() { memset(len, , si ...

  4. codeforces 486 D. Valid Sets(树形dp)

    题目链接:http://codeforces.com/contest/486/problem/D 题意:给出n个点,还有n-1条边的信息,问这些点共能构成几棵满足要求的树,构成树的条件是. 1)首先这 ...

  5. WPF 字体图标样式

    1.在网上下载Font ICO 字体字体压缩包 Font Awesome 矢量图标库    2.下载到的压缩包,解压后获得图标字体文件        3.然后把字体文件夹拷贝到项目中,目录为(/fon ...

  6. Python---网络爬虫初识

    1. 网络爬虫介绍 来自wiki的介绍: 网络爬虫(英语:web crawler),也叫网上蜘蛛(spider),是一种用来自动浏览万维网的网络机器人. 但是我们在写网络爬虫时还要注意遵守网络规则,这 ...

  7. 几个Python爬虫工具介绍

    Request Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用 上面一句话 出自Requests官方文档的第一句,从而奠定了其逗逼的文档风格.类似的还有: 警告: ...

  8. 【Nginx】应用场景

    一.概述 二.Nginx虚拟主机配置 2.1 外网映射工具 2.2 基于虚拟主机配置域名 2.3 基于端口的虚拟主机 三.Nginx配置反向代理 3.1 反向代理的作用 3.2 反向代理的好处 3.3 ...

  9. 【LeetCode】78-子集

    题目描述 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] 输出: [ [3], [1], [ ...

  10. Vue兄弟组件通信

    Vue兄弟组件通信之借助中央事件总线 下载链接:https://www.yinxiangit.com 其实要实现兄弟组件通信,就算是通过父子组件通信的方式也是可以达到的,如 子 ——>父——&g ...