什么是单向循环链表

单向循环链表基本与单向链表相同,唯一的区别就是单向循环链表的尾节点指向的不是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. js获取Cookie,获取url参数

    function getCookie(name) { var strCookie = document.cookie; var arrCookie = strCookie.split("; ...

  2. MSIL实用指南-生成while语句

    本篇讲解怎样生成while语句.while语句是编程语言中很重要的循环语句,它的结构是while(<表达式>) <语句或语句块> 当表达式的结果为true时就一直执行语句或语句 ...

  3. codeforces 820 C. Mister B and Boring Game(找规律)

    题目链接:http://codeforces.com/contest/820/problem/C 题解:显然a<=b的规律很好找只要 例如a=2,b=5,只要这样排列就行abbbbbbabbbb ...

  4. poj 3616 Milking Time (基础dp)

    题目链接 http://poj.org/problem?id=3616 题意:在一个农场里,在长度为N个时间可以挤奶,但只能挤M次,且每挤一次就要休息t分钟: 接下来给m组数据表示挤奶的时间与奶量求最 ...

  5. "ANDROID" 支持的KEYCODE

      例子: adb shell input text keyevent 4 0 -->  "KEYCODE_UNKNOWN" 1 -->  "KEYCODE_ ...

  6. 在docker上编译openjdk8

    以前曾经试过在VMware上安装linux,再在linux上编译openjdk8,但是每次都不顺利,例如linux环境,预装依赖软件,openjdk源码的选择等环境都会遇到问题,一旦失败再重新开始挺费 ...

  7. Elasticsearch 顶尖高手(1)

    1.什么是搜索? 百度 = 搜索,这是不对的 垂直搜索(站内搜索) 互联网的搜索:电商网站,招聘网站,新闻网站,各种app IT系统的搜索:OA软件,办公自动化软件,会议管理,项目管理,员工管理 搜索 ...

  8. linux ubuntu 18首次使用root权限

    第一次获得root密码: sudo passwd root 切换成root用户,获得root权限 exit 退出,回到初始用户

  9. ReentrantReadWriteLock总结

    ReentrantReadWriteLock的流程的一些特性: // ReentrantReadWriteLock.WriteLock.lock()特性: • 已持有读锁的线程不能再持有写锁: • 已 ...

  10. 对于synchronized的理解

    一.synchronized 同步关键字,分为同步代码块和同步函数 二.对synchronized的理解(未加static关键字)(以下所说:对同步方法和同步代码块均适用) 对象的创建是以类为模板的 ...