主要分析示例:

一、循环链表简述

二、单链表循环链表

三、双链表循环链表

一、循环链表简述

循环链表即链表形成了一个循环的结构,尾节点不再指向NULL,而是指向头节点HEAD,此时判定链表的结束是尾节点是否指向了头节点HEAD。基本结构为:

备注:其中单链表节点和双链表节点类和接口ICommOperate<T>与上篇一致,这里不在赘述。参考:JAVA链表操作:单链表和双链表http://www.cnblogs.com/xiaoxing/p/5969133.html

二、单链表循环链表

package LinkListTest;
import java.util.HashMap;
import java.util.Map;
public class SingleCycleLinkList implements ICommOperate<SNode> {
private SNode head = new SNode("HEAD") ; // 公共头指针,声明之后不变
private int size = 0 ;
public int getSize() {
return this.size;
} /*
* 链表插入,每次往末端插入,判定末端的标准为next是否指向head
* */
@Override
public boolean insertNode(SNode node) {
boolean flag = false ; initLinkList() ; // 初始化链表
if( this.size==0 ){ // 空链表
this.head.setNextNode(node) ;
node.setNextNode(this.head) ;
}else{
SNode current = this.head ;
while( current.getNextNode()!=this.head ){ // 找到末端节点
current = current.getNextNode() ;
}
current.setNextNode(node) ;
node.setNextNode(this.head) ; // 循坏链表,尾节点指向head
}
this.size++ ;
flag = true ; return flag;
} /*
* 插入链表指定位置pos,从1开始,而pos大于size则插入链表末端
* */
@Override
public boolean insertPosNode(int pos, SNode node) {
boolean flag = true ;
SNode current = this.head.getNextNode() ; initLinkList() ;// 初始化链表
if( this.size==0 ){ // 链表为空
this.head.setNextNode(node) ;
node.setNextNode(this.head) ;// 循坏链表,尾节点指向head
this.size++ ;
}else if( this.size<pos ){ // pos位置大于链表长度,插入末端
insertNode(node) ;
}else if( pos>0 && pos<=this.size ){ // 链表内节点
// 1、找到要插入pos位置节点和前节点,node将插入两个节点之间
int find = 0;
SNode preNode = this.head; // 前节点
SNode currentNode = current; // 当前节点
while( find<pos-1 && currentNode!=this.head ){
preNode = current ; // 前节点后移
currentNode = currentNode.getNextNode() ; // 当前节点后移
find++ ;
if( find<pos-1 && currentNode!=this.head ){ // 未结束寻找节点前,后移前节点
current = current.getNextNode() ;
}
}
// System.out.println(preNode);
// System.out.println(currentNode); // 2、插入节点
preNode.setNextNode(node);
node.setNextNode(currentNode);
this.size++ ;
}else {
System.out.println("位置信息错误");
flag = false ;
} return flag;
} private void initLinkList(){
if( size==0 ){
this.head.setNextNode(this.head);
}
} /*
* 指定链表的节点pos,删除对应节点。方式:找到要删除节点的前后节点,进行删除,下标从1开始
* */
@Override
public boolean deleteNode(int pos) {
boolean flag = false;
SNode current = this.head.getNextNode() ;
if( pos<=0 || pos>this.size || current==this.head ){
System.out.println("位置信息错误或链表无信息");
}else{
// 1、找到要删除节点的前后节点
int find = 0;
SNode preNode = this.head; // 前节点
SNode nextNode = current.getNextNode(); // 后节点
while( find<pos-1 && nextNode!=this.head ){
preNode = current ; // 前节点后移
nextNode = nextNode.getNextNode() ; // 后节点后移
find++ ;
if( find<pos-1 && nextNode!=this.head ){ // 未结束找节点前,后移"前节点"
current = current.getNextNode() ;
}
}
// System.out.println(preNode);
// System.out.println(nextNode); // 2、删除节点
preNode.setNextNode(nextNode);
System.gc(); // 回收删除节点
this.size-- ;
flag = true ;
} return flag;
} /*
* 指定链表的节点pos,修改对应节点,下标从1开始
* */
@Override
public boolean updateNode(int pos, Map<String, Object> map) {
boolean flag = false ;
SNode node = getNode(pos, map); // 获得相应位置pos的节点
if( node!=null ){
String data = (String) map.get("data") ;
node.setData(data);
flag = true ;
}
return flag;
} /*
* 找到指定链表的节点pos,下标从1开始
* */
@Override
public SNode getNode(int pos, Map<String, Object> map) {
SNode current = this.head.getNextNode() ;
if( pos<=0 || pos>this.size || current==this.head ){
System.out.println("位置信息错误或链表不存在");
return null;
}
int find = 0 ;
while( find<pos-1 && current!=this.head ){
current = current.getNextNode() ;
find++ ;
}
return current;
} /*
* 打印链表
* */
@Override
public void printLink() {
int length = this.size ;
if( length==0 ){
System.out.println("链表为空!");
return ;
}
SNode current = this.head.getNextNode() ;
System.out.println("总共有节点数: " + length +" 个");
int find = 0 ;
while( current!=this.head ){
System.out.println("第 " + (++find) + " 个节点 :" + current);
current=current.getNextNode() ;
}
} public static void main(String[] args) {
SingleCycleLinkList scll = new SingleCycleLinkList() ;
SNode node1 = new SNode("节点1");
SNode node2 = new SNode("节点2");
SNode node3 = new SNode("节点3");
SNode node4 = new SNode("节点4");
SNode node5 = new SNode("节点5");
SNode node6 = new SNode("插入指定位置");
// scll.insertPosNode(scll.getSize()+1, node1) ;
// scll.insertPosNode(scll.getSize()+1, node2) ;
// scll.insertPosNode(scll.getSize()+1, node3) ;
// scll.insertPosNode(scll.getSize()+1, node4) ;
// scll.insertPosNode(scll.getSize()+1, node5) ;
scll.insertNode(node1);
scll.insertNode(node2);
scll.insertNode(node3);
scll.insertNode(node4);
scll.insertNode(node5); System.out.println("*******************输出链表*******************");
scll.printLink(); System.out.println("*******************获得指定链表节点*******************");
int pos = 2 ;
System.out.println("获取链表第 "+pos+" 个位置数据 :"+scll.getNode(pos, null)); System.out.println("*******************向链表指定位置插入节点*******************");
int pos1 = 3 ;
System.out.println("将数据插入第"+pos1+"个节点:");
scll.insertPosNode(pos1, node6) ;
scll.printLink(); System.out.println("*******************删除链表指定位置节点*******************");
int pos2 = 3 ;
System.out.println("删除第"+pos2+"个节点:");
scll.deleteNode(pos2) ;
scll.printLink(); System.out.println("*******************修改链表指定位置节点*******************");
int pos3 = 3 ;
System.out.println("修改第"+pos3+"个节点:");
Map<String, Object> map = new HashMap<>() ;
map.put("data", "this is a test") ;
scll.updateNode(pos3, map) ;
scll.printLink();
} }

、双链表循环链表

package LinkListTest;

import java.util.HashMap;
import java.util.Map; public class DoubleCycleLinkList implements ICommOperate<DNode>{
private DNode head = new DNode("HEAD"); // 公共头指针,声明之后不变
private int size = 0 ; // 记录链表节点数量 public int getSize() {
return this.size;
} /*
* 链表插入,每次往末端插入,判定末端的标准为next是否指向head
* */
@Override
public boolean insertNode(DNode node) {
boolean flag = false ; initLinkList() ; // 初始化链表
DNode current = this.head ;
if( this.size==0 ){ // 空链表
this.head.setNextNode(node) ;
node.setPriorNode(this.head);
node.setNextNode(this.head) ;
}else{ // 链表内节点
while( current.getNextNode()!=this.head ){ // 找到末端节点
current = current.getNextNode() ;
}
current.setNextNode(node) ;
node.setPriorNode(current);
node.setNextNode(this.head) ; // 循坏链表,尾节点指向head
}
this.size++ ;
flag = true ; return flag;
} /*
* 插入链表指定位置pos,从1开始,而pos大于size则插入链表末端
* */
@Override
public boolean insertPosNode(int pos, DNode node) {
boolean flag = true; initLinkList() ; // 初始化链表
DNode current = this.head.getNextNode() ;
if( this.size==0 ){ // 链表为空
this.head.setNextNode(node) ;
node.setPriorNode(this.head);
node.setNextNode(this.head) ;
this.size++ ;
}else if( pos>this.size ){ // pos位置大于链表长度,插入末端
insertNode(node) ;
}else if( pos>0 && pos<=this.size ){ // 链表内节点
// 1、找到要插入位置pos节点,插入pos节点当前位置
int find = 0;
while( find<pos-1 && current.getNextNode()!=this.head ){
current = current.getNextNode() ;
find++ ;
}
// 2、插入节点
if( current.getNextNode()==this.head ){ // 尾节点
node.setPriorNode(current);
node.setNextNode(this.head);
current.setNextNode(node);
} else if( current.getNextNode()!=this.head ) { //中间节点
node.setPriorNode(current.getPriorNode());
node.setNextNode(current);
current.getPriorNode().setNextNode(node);
current.setPriorNode(node);
}
this.size++ ;
}else{
System.out.println("位置信息错误");
flag = false ;
}
return flag;
} private void initLinkList(){
if( size==0 ){
this.head.setNextNode(this.head);
this.head.setPriorNode(this.head);
}
} /*
* 指定链表的节点pos,删除对应节点。方式:找到要删除节点的前后节点删除,下标从1开始
* */
@Override
public boolean deleteNode(int pos) {
boolean flag = false;
DNode current = this.head.getNextNode() ;
if( pos<=0 || pos>this.size || current==this.head ){
System.out.println("位置信息错误或链表不存在");
}else{
// 1、找到要删除位置pos节点
int find = 0;
while( find<pos-1 && current.getNextNode()!=this.head ){
current = current.getNextNode() ;
find++ ;
}
// 2、删除节点
if( current.getNextNode()==this.head ){ // 尾节点
current.getPriorNode().setNextNode(this.head) ;
} else if( current.getNextNode()!=this.head ) { //中间节点
current.getPriorNode().setNextNode(current.getNextNode()) ;
current.getNextNode().setPriorNode(current.getPriorNode()) ;
}
System.gc(); // 回收删除节点
this.size-- ;
flag = true ;
}
return flag;
} /*
* 指定链表的节点pos,修改对应节点,下标从1开始
* */
@Override
public boolean updateNode(int pos, Map<String, Object> map) {
boolean flag = false ;
DNode node = getNode(pos, map);
if( node!=null ){
String data = (String) map.get("data") ;
node.setData(data);
flag = true ;
}
return flag;
} /*
* 找到指定链表的节点pos,下标从1开始
* */
@Override
public DNode getNode(int pos, Map<String, Object> map) {
DNode current = this.head.getNextNode() ;
if( pos<=0 || pos>this.size || current==this.head ){
System.out.println("位置信息错误或链表不存在");
return null;
}
int find = 0 ;
while( find<pos-1 && current!=this.head ){
current = current.getNextNode() ;
find++ ;
}
return current;
} /*
* 打印链表
* */
@Override
public void printLink() {
int length = this.size ;
if( length==0 ){
System.out.println("链表为空!");
return ;
}
DNode current = this.head.getNextNode() ;
int find = 0 ;
System.out.println("总共有节点数: " + length +" 个");
while( current!=this.head ){
System.out.println("第 " + (++find) + " 个节点 :" + current);
current=current.getNextNode() ;
}
} public static void main(String[] args) {
DoubleCycleLinkList dcll = new DoubleCycleLinkList() ;
DNode node1 = new DNode("节点1");
DNode node2 = new DNode("节点2");
DNode node3 = new DNode("节点3");
DNode node4 = new DNode("节点4");
DNode node5 = new DNode("节点5");
DNode node6 = new DNode("插入指定位置");
dcll.insertPosNode(10, node1) ;
dcll.insertPosNode(10, node2) ;
dcll.insertPosNode(8, node3) ;
dcll.insertPosNode(88, node4) ;
dcll.insertPosNode(8, node5) ;
// dcll.insertNode(node1);
// dcll.insertNode(node2);
// dcll.insertNode(node3);
// dcll.insertNode(node4);
// dcll.insertNode(node5); System.out.println("*******************输出链表*******************");
dcll.printLink(); System.out.println("*******************获得指定链表节点*******************");
int pos = 2 ;
System.out.println("获取链表第 "+pos+"个位置数据 :"+dcll.getNode(pos, null)); System.out.println("*******************向链表指定位置插入节点*******************");
int pos1 = dcll.getSize()+1 ;
System.out.println("将数据插入第"+pos1+"个节点:");
dcll.insertPosNode(pos1, node6) ;
dcll.printLink(); System.out.println("*******************删除链表指定位置节点*******************");
int pos2 = 7 ;
System.out.println("删除第"+pos2+"个节点:");
dcll.deleteNode(pos2) ;
dcll.printLink(); System.out.println("*******************修改链表指定位置节点*******************");
int pos3 = 3 ;
System.out.println("修改第"+pos3+"个节点:");
Map<String, Object> map = new HashMap<>() ;
map.put("data", "this is a test") ;
dcll.updateNode(pos3, map) ;
dcll.printLink();
}
}

JAVA 链表操作:循环链表的更多相关文章

  1. JAVA 链表操作:单链表和双链表

    主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...

  2. Java链表操作代码

    /** * */ package com.cherish.SwordRefersToOffer; /** * @author acer * */ public class test_22链表中倒数第k ...

  3. Java 链表

    按链表的组织形式分有ArrayList和LinkList两种.ArrayList内部其实是用数组的形式实现链表,比较适合链表大小确定或较少对链表进行增删操作的情况,同时对每个链表节点的访问时间都是co ...

  4. Java链表基本操作和Java.util.ArrayList

    Java链表基本操作和Java.util.ArrayList 今天做了一道<剑指offer>上的一道编程题“从尾到头打印链表”,具体要求如下:输入一个链表,按链表值从尾到头的顺序返回一个A ...

  5. JAVA链表中迭代器的实现

    注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...

  6. linux 内核的链表操作(好文不得不转)

    以下全部来自于http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 无任何个人意见. 本文详细分析了 2.6.x 内 ...

  7. Java数组操作的10大方法

    转载自码农网 译文链接:http://www.codeceo.com/article/10-java-array-method.html 英文原文:Top 10 Methods for Java Ar ...

  8. Java链表设计

    链表 1,链表的实现 在实际开发之中对象数组是一项非常实用的技术,并且利用其可以描述出“多”方的概念,例如:一个人有多本书,则在人的类里面一定要提供有一个对象数组保存书的信息,但是传统的对象数组依赖于 ...

  9. Python链表操作(实现)

    Python链表操作 在Python开发的面试中,我们经常会遇到关于链表操作的问题.链表作为一个非常经典的无序列表结构,也是一个开发工程师必须掌握的数据结构之一.在本文中,我将针对链表本身的数据结构特 ...

随机推荐

  1. 简单了解JS 中的indexOf方法

    indexOf() 方法返回指定值在字符串对象中首次出现的位置.从 fromIndex 位置开始查找,如果不存在,则返回 -1. 首先先看下MDN下的参考文档,文档里列出的很详细,这里我只列出了注意点 ...

  2. 不care小米,梁军坦言微鲸才是乐视最大对手

    除了每天毫无悬念地上头条和陷入困境的生态帝国之外,乐视还要继续操心着它的对手们."挑事儿"的小米已经不足为惧,后起之秀微鲸成了一个令它"头疼"的所在.因为,不仅 ...

  3. sun.misc.BASE64Encoder找不到jar包的解决方法

    1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...

  4. Qt 之 数字钟

    本例用来展示 QTimer 的使用,如何定时的更新一个窗口部件. 1  QLCDNumber 类 QLCDNumber 是一种可将数字显示为类似 LCD 形式的窗口部件,它同 QLabel 一样,都继 ...

  5. iOS中多线程知识总结(一)

    这一段开发中一直在处理iOS多线程的问题,但是感觉知识太散了,所以就把iOS中多线程的知识点总结了一下. 1.基本概念 1)什么是进程?进程的特性是什么? 进程是指在系统中正在运行的一个应用程序.   ...

  6. SQL Server 创建数据库邮件

    一. 背景 数据库发邮件通知数据库的运行状态(状态可以通过JOB形式获取)和信息,达到预警的效果. 二. 基础知识 msdb系统数据库保存有关Job,Database Mail,Nodifyicati ...

  7. SQL Server 2014新特性探秘(1)-内存数据库

    简介    SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQL PASS Summit 2012的开幕式时,微软就宣布 ...

  8. 《JS设计模式笔记》 1,单例模式

    <script type="text/javascript"> //单例模式 //1,每次点击都会生成一个新的div var createMask=function ( ...

  9. C#单例模式详解

    C#要实现单例模式必须要有以下三点: 声明私有静态成员.私有化构造函数.静态函数返回实例. private static GameManager s_GameManager=null; private ...

  10. 虚拟化 - 每天5分钟玩转 OpenStack(2)

    OpenStack是云操作系统,要学习OpenStack,首先需要掌握一些虚拟化和云计算的相关知识. 虚拟化 虚拟化是云计算的基础.简单的说,虚拟化使得在一台物理的服务器上可以跑多台虚拟机,虚拟机共享 ...