JAVA 数据结构链表操作循环链表

JAVA 链表操作:循环链表

主要分析示例:

一、单链表循环链表

二、双链表循环链表

其中单链表节点和双链表节点类和接口ICommOperate<T>与上篇一致,这里不在赘述。参考:JAVA链表操作:单链表和双链表http://www.jb51.net/article/95113.htm

一、单链表循环链表


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();
  }
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java 数据结构单链表的实现

    java 数据结构单链表的实现 单链表实现链表的打印及元素删除操作,链表的实现主要是next属性的定义,将一堆节点关联起来的.实现简单的链表如下: public class LinkNode { private int value; private LinkNode next; public LinkNode(int x) { value = x; } public LinkNode getNext(){ return next; } public void setNext(LinkNode n

  • java数据结构之实现双向链表的示例

    复制代码 代码如下: /** * 双向链表的实现 * @author Skip * @version 1.0 */public class DoubleNodeList<T> { //节点类 private static class Node<T>{  Node<T> perv;  //前节点  Node<T> next;  //后节点  T data;    //数据 public Node(T t){   this.data = t;  } } priv

  • Java数据结构之链表(动力节点之Java学院整理)

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) find:查找包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) remove:删除包含指定关键字的链接点,由于需要遍历查找,平均需要查找N/2次,即O(N) public class LinkedList { private class Data{ private Object obj; private Data next =

  • java实现数据结构单链表示例(java单链表)

    复制代码 代码如下: /** * 单向链表 * */public class NodeList<E> { private static class Node<E> { // 节点类  E data; // 节点上的数据  Node<E> next; // 指向下一个节点 Node(E e) {   this.data = e;   this.next = null;  } } private Node<E> head; // 链表的头节点 private N

  • Java模拟单链表和双端链表数据结构的实例讲解

    模拟单链表 线性表: 线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构. 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的. 线性表的逻辑结构简单,便于实现和操作. 在实际应用中,线性表都是以栈.队列.字符串等特殊线性表的形式来使用的. 线性结构的基本特征为: 1.集合中必存在唯一的一个"第一元素": 2.集合中必存在唯一的一个 "最后元素" : 3.除最后一个元素之外,均有 唯一的后继(后件):

  • Java 数据结构链表操作实现代码

    链表是一种复杂的数据结构,其数据之间的相互关系使链表分成三种:单链表.循环链表.双向链表,下面将逐一介绍.链表在数据结构中是基础,也是重要的知识点,这里讲下Java 中链表的实现, JAVA 链表操作:单链表和双链表 主要讲述几点: 一.链表的简介 二.链表实现原理和必要性 三.单链表示例 四.双链表示例 一.链表的简介 链表是一种比较常用的数据结构,链表虽然保存比较复杂,但是在查询时候比较便捷,在多种计算机语言都相应的应用,链表有多种类别,文章针对单链表和双链表进行分析.链表中数据就像被一个链

  • Java数据结构之双端链表原理与实现方法

    本文实例讲述了Java数据结构之双端链表原理与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.什么时双端链表: 链表中保持这对最后一个连点引用的链表 2.从头部插入 要对链表进行判断,如果为空则设置尾节点为新添加的节点 3.从尾部进行插入 如果链表为空,则直接设置头节点为新添加的节点,否则设置尾节点的后一个节点为新添加的节点 4.从头部删除 判断节点是否有下个节点,如果没有则设置节点为null 二.具体实现 /** * @描述 头尾相接的链表 * @项目名称 Java_DataStr

  • Java数据结构之简单链表的定义与实现方法示例

    本文实例讲述了Java数据结构之简单链表的定义与实现方法.分享给大家供大家参考,具体如下: 一.概述: 1.原理: 只有一个数据项(链接点Link),每个数据插入时都是对第一个数据的引用. 2.插入数据说明: 当链表没有数据时,插入的值就是第一个数据,如果链表里有数据,就把当前的数据的next指针指向第一个数据. 3.插入数据图: 4.特点:先进后出 5.实现功能: 数据插入,指定位置插入,显示,查询,删除等 6.删除原理 7.插入头节点原理 二.实现: 1.创建节点 /** * @描述 节点

  • 详解java数据结构与算法之双链表设计与实现

    在单链表分析中,我们可以知道每个结点只有一个指向后继结点的next域,倘若此时已知当前结点p,需要查找其前驱结点,那么就必须从head头指针遍历至p的前驱结点,操作的效率很低,因此如果p有一个指向前驱结点的next域,那效率就高多了,对于这种一个结点中分别包含了前驱结点域pre和后继结点域next的链表,称之为双链表.本篇我们将从以下结点来分析双链表 双链表的设计与实现 双链表的主要优点是对于任意给的结点,都可以很轻易的获取其前驱结点或者后继结点,而主要缺点是每个结点需要添加额外的next域,因

  • java 数据结构之删除链表中的元素实例代码

    java 删除链表中的元素 以下实例演示了使用 Clear() 方法来删除链表中的元素: import java.util.*; public class Main { public static void main(String[] args) { LinkedList<String> lList = new LinkedList<String>(); lList.add("1"); lList.add("8"); lList.add(&q

  • Java模拟有序链表数据结构的示例

    有序链表: 按关键值排序.删除链头时,就删除最小(/最大)的值,插入时,搜索插入的位置. 插入时需要比较O(N),平均O(N/2),删除最小(/最大)的在链头的数据时效率为O(1), 如果一个应用需要频繁的存取(插入/查找/删除)最小(/最大)的数据项,那么有序链表是一个不错的选择 优先级队列 可以使用有序链表来实现 有序链表的插入排序: 对一个无序数组,用有序链表来排序,比较的时间级还是O(N^2) 复制时间级为O(2*N),因为复制的次数较少,第一次放进链表数据移动N次,再从链表复制到数组,

随机推荐