前言:前面几篇介绍了线性表的顺序和链式存储结构,其中链式存储结构为单向链表(即一个方向的有限长度、不循环的链表),对于单链表,由于每个节点只存储了向后的指针,到了尾部标识就停止了向后链的操作。也就是说只能向后走,如果走过了,就回不去了,还得重头开始遍历,所以就衍生出了循环链表

  定义:将单链表中中断结点的指针端有空指针改为指向头结点,就使整个单链表形成一个环,这种头尾详解的单链表称为单循环链表,简称循环链表;
数据结构与算法(四)-线性表之循环链表

 

数据结构与算法(四)-线性表之循环链表
  特性:  
  • 若链表为空,则头结点的next结点还是指向其本身,即head.next=head;
  • 尾节点的next指针指向head结点,即头尾相连;
  • 判断是否遍历了完,直接判断next==head即可;
  • 由单链表变化的循环也成为单向循环链表;
  • 循环链表的特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活;

二、单向循环链表的实现

  循环链表是在单链表(线性单链表)的基础上,将尾节点的next指向了head,所以基本的结构是类似的,所以下面,直接贴代码了;
  
public class LoopChain<T> {

    //尾结点直接引用
    private Node<T> tail;

    //链长度
    private Integer size;

    //初始化
    LoopChain() {
        tail = new Node<T>();
        tail.setNext(tail);
    }

    public Node<T> remove(Integer index) throws Exception {
        //获取该位置的上一个节点
        Node<T> s = getNode(index - 1);
        //获取该位置节点的下一个节点
        Node<T> next = getNode(index).getNext();
        //将本节点的next节点放在本节点的前一个节点的next节点位置
        s.setNext(next.getNext());
        return next;
    }

    public void add(T t,Integer index) throws Exception {
        //获取该位置的上一个节点
        Node<T> s = getNode(index - 1);
        //创建新节点
        Node<T> p = new Node<>();
        p.setObject(t);
        //将本节点的next节点放入新节点的next节点
        p.setNext(s.getNext());
        //将新节点放入本节点的next节点位置
        s.setNext(p);
    }

    public T get(Integer index) throws Exception {
        return (T)getNode(index).getObject();
    }

    private Node<T> getNode(Integer index) throws Exception {
        if (index > size || index < 0)
            throw new Exception("index outof length");
        //取头节点
        Node<T> p = tail.next;
        for (int i = 0; i < index; i++)
            p = p.getNext();
        return p;
    }

    class Node<T> {

        private Object object;

        private Node next;

        public Object getObject() {
            return object;
        }

        public void setObject(Object object) {
            this.object = object;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }

    }

}
LoopChain.java

  获取元素:

    public T get(Integer index) throws Exception {
        return (T)getNode(index).getObject();
    }

    private Node<T> getNode(Integer index) throws Exception {
        if (index > size || index < 0)
            throw new Exception("index outof length");
        //取头节点
        Node<T> p = tail.next;
        for (int i = 0; i < index; i++)
            p = p.getNext();
        return p;
    }

  插入元素:

    public void add(T t,Integer index) throws Exception {
        //获取该位置的上一个节点
        Node<T> s = getNode(index - 1);
        //创建新节点
        Node<T> p = new Node<>();
        //将本节点的next节点放入新节点的next节点
        p.setNext(s.getNext());
        //将新节点放入本节点的next节点位置
        s.setNext(p);
    }

  移除元素:

    public Node<T> remove(Integer index) throws Exception {
        //获取该位置的上一个节点
        Node<T> s = getNode(index - 1);
        //获取该位置节点的下一个节点
        Node<T> next = getNode(index).getNext();
        //将本节点的next节点放在本节点的前一个节点的next节点位置
        s.setNext(next.getNext());
        return next;
    }

相关文章: