JAVA 链表操作:循环链表
主要分析示例:
一、循环链表简述
二、单链表循环链表
三、双链表循环链表
一、循环链表简述
循环链表即链表形成了一个循环的结构,尾节点不再指向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 链表操作:循环链表的更多相关文章
- JAVA 链表操作:单链表和双链表
主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都 ...
- Java链表操作代码
/** * */ package com.cherish.SwordRefersToOffer; /** * @author acer * */ public class test_22链表中倒数第k ...
- Java 链表
按链表的组织形式分有ArrayList和LinkList两种.ArrayList内部其实是用数组的形式实现链表,比较适合链表大小确定或较少对链表进行增删操作的情况,同时对每个链表节点的访问时间都是co ...
- Java链表基本操作和Java.util.ArrayList
Java链表基本操作和Java.util.ArrayList 今天做了一道<剑指offer>上的一道编程题“从尾到头打印链表”,具体要求如下:输入一个链表,按链表值从尾到头的顺序返回一个A ...
- JAVA链表中迭代器的实现
注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...
- linux 内核的链表操作(好文不得不转)
以下全部来自于http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 无任何个人意见. 本文详细分析了 2.6.x 内 ...
- Java数组操作的10大方法
转载自码农网 译文链接:http://www.codeceo.com/article/10-java-array-method.html 英文原文:Top 10 Methods for Java Ar ...
- Java链表设计
链表 1,链表的实现 在实际开发之中对象数组是一项非常实用的技术,并且利用其可以描述出“多”方的概念,例如:一个人有多本书,则在人的类里面一定要提供有一个对象数组保存书的信息,但是传统的对象数组依赖于 ...
- Python链表操作(实现)
Python链表操作 在Python开发的面试中,我们经常会遇到关于链表操作的问题.链表作为一个非常经典的无序列表结构,也是一个开发工程师必须掌握的数据结构之一.在本文中,我将针对链表本身的数据结构特 ...
随机推荐
- R in Action 读书笔记(6)基本图形
MindMapper原文件
- [ASP.NET MVC 小牛之路]08 - Area 使用
ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Area 使每个功能模块都有各自的文件夹,文件夹中有自己的Cont ...
- 查看html元素绑定的事件与方法的利器
WEB标准提倡结构.表现和行为相 分离,现在越来越多采用这种表现和行为的方式,但它也为我们开发调试带来一些问题,网页载入一堆JavaScript,,我们很难搞清楚最后在哪些元素的哪个动作绑定了事件,尤 ...
- iOS-iOS开发简单介绍
概览 终于到了真正接触IOS应用程序的时刻了,之前我们花了很多时间去讨论C语言.ObjC等知识,对于很多朋友而言开发IOS第一天就想直接看到成果,看到可以运行的IOS程序.但是这里我想强调一下,前面的 ...
- Nginx与Apache比较
Nginx特点:高性能epoll 异步非阻塞多个连接(万级别)可以对应一个进程 支持反向代理支持7层负载均衡静态文件.反向代理.前端缓存等处理方便支持高并发连接,每秒最多的并发连接请求理论可以达到 5 ...
- js深浅复制
一.数组的深浅拷贝 <body> <script type="text/javascript"> var arr = ["One",&q ...
- Mysql命令show global status求根溯源
近来,发现好多公司对mysql的性能监控是通过show global status实现的,因此对于这个命令想要探究一番,看他是否是实时更新的. 在此之前,我们必须搞明白mysql对于这个命令的执行过程 ...
- 【原创】开源Math.NET基础数学类库使用(04)C#解析Matrix Marke数据格式
本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 开源Math.NET基础数学类库使用总目录:[目录]开源Math.NET基础数学类库使用总目录 前言 ...
- C语言之通过冒泡排序浅谈编程思想
写这篇博文的目的是想起到抛砖引玉的作用,还请大牛们留下一些先进的思想,让小菜学习一下.下面入正题. 复习C语言怎么能少的了冒泡呢,记得刚学C语言那会,感觉冒泡排序真的太复杂了,理解不大了,嗯!还是当时 ...
- c# 我所理解的 值类型 and 引用类型
一直以来对于值类型和引用类型都只是一个模糊的概念,趁最近有空深入理解了下. 先说说值类型,在msdn上是这样介绍值类型的. 意思就是值类型直接包含值. 变量引用的位置就是值所在内存中实际存储的位置,所 ...