java循环单链表

package com.demo;

/**
 * java循环单链表
 * 循环链表的最后一个结点的指针是指向该循环链表的第一个结点或表头结点,从而构成环形链表。
 * @author jackie
 * 循环链表的运算与单链表的运算基本一致。所不同的有以下几点:
 * 1、在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为NULL。此种情况还试用于在最后一个结点后插入一个新的结点。
 * 2、在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到表尾。而非象单链表那样判断链域值是否为NULL。
 */
public class CycleSingleLinkedList<T> {
  /**
   * 结点类
   */
  private static class Node<T>{
    T nodeValue;    //数据域
    Node<T> next;   //指针域保存着下一节点的引用
    
    Node(T nodeValue,Node<T> next){
      this.nodeValue = nodeValue;
      this.next = next;
    }
    
    Node(T nodeValue){
      this(nodeValue, null);
    }
  }
  
  //下面是SingleLinkedList类的数据成员和方法
  private Node<T> head;
  private int length;       //the length of the list
  //构造函数,初始化列表头和列表尾
  public CycleSingleLinkedList(){
    head = null;
    length = 0;
  }
  /**
   * 判断链表是否为空
   * @return
   */
  public boolean isEmpty(){
    return head == null;
  }
  /**
   * 创建头指针,该方法只用一次
   * @param item
   */
  public void addToHead(T item){
    head = new Node<T>(item);
    head.next = head;
    length = 1;
  }

  /**
   * 打印列表
   */
  public void printList(){
    if(isEmpty()){
      System.out.println("null");
    }else{
      Node<T> p = head; 
      System.out.println(p.nodeValue);
      while(p.next != head){
        p = p.next;
        System.out.println(p.nodeValue);
      }
    }
  }
  /**
   * 在表头插入结点
   * @param item
   */
  public void addFirst(T item){
    Node<T> p = head;
    if(isEmpty())
      addToHead(item);
    else{
      Node<T> newNode = new Node<T>(item,head);
      while(head != p.next) p = p.next;
      p.next = newNode;
      head = newNode;
      length ++;
    }
  }
  /**
   * 在表尾插入结点
   * @param item
   */
  public void addLast(T item){
    Node<T> newNode = new Node<T>(item,head);
    Node<T> p = head;
    while(p.next != head)p = p.next;
    p.next = newNode;
    length ++;
  }
  /**
   * 在表头删除结点
   */
  public void removeFirst(){
    if(!isEmpty()){
      Node<T> p = head;
      while(p.next != head) p = p.next;
      head = head.next;
      p.next = head;
      length --;
    }
    else System.out.println("The list have bean emptied!");
  }
  /**
   * 在表尾删除结点
   */
  public void removeLast(){
    Node<T> prev = null, curr = head;
    while(curr.next != head){
      prev = curr;
      curr = curr.next;
    }
    prev.next = head;
    length --;
  }
  /**
   * 插入一个新结点的操作可能有四种情况:
   * ①表为空,调用addToHead方法
   * ②表非空,插入指定元素
   * ③表非空,但是指定nodeValue不存在
   * @param appointedItem 指定的nodeValue
   * @param item 要插入的结点
   * @return 成功插入返回true
   */
  public boolean insert(T appointedItem,T item){
    Node<T> p = head,c = head.next,newNode = new Node<T>(item);
    boolean flag = false;//③
    if(!isEmpty()){ // ①
      while(c.next != head.next){
        if(c.nodeValue.equals(appointedItem)){
          newNode.next = c ;
          p.next = newNode;
          flag = true;
          break;
        }
        p = c;
        c = c.next;
      }
      if(!flag && c.nodeValue.equals(appointedItem)){
        newNode.next = c;
        p.next = newNode;
        head = newNode;
        flag = true;
      }
      return flag;
    }else{
      addToHead(item);
      flag = true;
      return flag;
    }
  }
  /**
   * 移除列表中首次出现的指定元素
   * 删除操作可能出现的情况:
   * ①表为空
   * ②被移除元素位于表头
   * ③被移除元素位于表其他部位
   * ④被移除元素不在表中
   * @param item
   */
  public void remove(T item){
    if(isEmpty()){
      System.out.println("remove lose! the list is null");
    }else{
      Node<T> p = head,c = head.next;
      while(c.next != head.next){
        if(c.nodeValue.equals(item)){
          p.next = c.next;
          length --;
          break;
        }else{
          p = c;
          c = c.next;
        }
      }
    }
  }
  /**
   * 返回列表中首次出现的指定元素的索引
   * 如果表中不包含指定元素则返回-1
   * @param item
   * @return
   */
  public int indexOf(T item){
    int index = -1;
    Node<T> p = head;
    if(length == 0){
      return index;
    }else if(length == 1 && head.nodeValue.equals(item)){
      return index ++;
    }else{
      if(p.nodeValue.equals(item)){
        return index+1;
      }
      index = 1;
      while (p.next != head) {
        if(item.equals(p.nodeValue)) return index;
        p = p.next;
        index ++;
      }
      return -1;
    }
  }
  /**
   * 如果此列表中包含指定元素,则返回 true
   * @param item
   * @return
   */
  public boolean contains(T item){
    return indexOf(item) != -1;
  }
  
  public static void main(String[] args) {
    CycleSingleLinkedList<String> t = new CycleSingleLinkedList<String>();
    t.addToHead("1");
    t.addFirst("2");
    t.addFirst("3");
    t.addLast("0");
//    t.removeFirst();
//    t.removeLast();
    t.insert("2", "2.1");
//    System.out.println(t.indexOf("2.1"));
//    System.out.println(t.contains("2.1"));
    t.printList();
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值