数据结构(三)——单向循环链表的java实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33127597/article/details/79714688

单向循环链表结构就是链表的最后一个指针不再是null,而是指向整个链表的第一个结点,使链表形成一个环。
这里写图片描述

上代码

package likend;

/**
 * Created by yxf on 2018/3/27.
 * 单向循环链表
 */
public class CycleLink<T> {

    private Node header;  //链表头结点
    private Node tail;    //链表尾结点
    private int size;     //保存已经有的结点

    public class Node<T> {
        private T data;   //数据
        private Node next; //指向下一个节点的引用

        public Node() {
        }

        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }

    public CycleLink() {
    }

    /**
     * 在尾部添加
     *
     * @param element
     * @return
     */
    public boolean add(T element) {
        linkLast(element);
        return true;
    }

    /**
     * 获取指定索引处的元素
     *
     * @param index
     * @return
     */
    public T getElement(int index) {
        return (T) getNodeByIndex(index).data;
    }

    /**
     * 获取指定位置的结点
     * @param index
     * @return
     */
    public Node getNodeByIndex(int index){
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("获取位置超过了链表长度范围");
        Node currentNode = header;
        for (int i = 0; i < index; i++) {
            currentNode = currentNode.next;
        }
        return currentNode;
    }

    /**
     * 获取指定位置前驱的结点
     * @param index
     * @return
     */
    public Node getNodeByIndexBefore(int index){
        Node preNode = header;
        for (int i = 0; i < index - 1; i++) {
            preNode = preNode.next;      //获得前驱结点
        }
        return preNode;
    }

    /**
     * 获取指定元素的前驱
     *
     * @param currentElem
     * @return
     */
    public T priorElement(T currentElem) {
        int index = getIndex(currentElem);
        if (index == -1)
            return null;
        else {
            if (index == 0) {
                return null;
            } else {
                return (T) getNodeByIndex(index - 1).data;
            }
        }
    }

    /**
     * 获取指定元素的后驱
     *
     * @param currentElem
     * @return
     */
    public T nextElement(T currentElem) {
        int index = getIndex(currentElem);
        if (index == -1)
            return null;
        else {
            if (index == size - 1) {
                return null;
            } else {
                return (T) getNodeByIndex(index + 1).data;
            }
        }
    }

    public int getIndex(T element) {
        Node current = header;
        for (int i = 0; i < size && current != null; i++, current = current.next) {
            if (current.data.equals(element))
                return i;
        }
        return -1;
    }

    /**
     * 在头部插入
     *
     * @param element
     * @return
     */
    public boolean addFirst(T element) {
        linkFirst(element);
        return true;
    }

    /**
     * 在指定位置插入元素
     *
     * @param index
     * @param element
     * @return
     */
    public boolean insert(int index, T element) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("插入位置超出链表范围");
        if (index == 0)
            linkFirst(element);
        else {
            Node preNode = getNodeByIndexBefore(index);
            Node newNode = new Node(element, null);
            newNode.next = preNode.next;
            preNode.next = newNode;
            size++;
        }
        return true;
    }

    /**
     * 删除元素
     *
     * @param index
     * @return
     */
    public T delete(int index) {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("删除位置超出链表范围");

        Node currentNode = header;
        if (index == 0) {
            header = header.next;
            currentNode.next = null;
            tail.next = header;
        } else {
            Node currentNodeBefore = null;
            for (int i = 0; i < index; i++) {
                currentNodeBefore = currentNode;//前置结点
                currentNode = currentNode.next;  //要删除的当前结点
            }
            //删除的是尾结点
            if(index == size - 1){
                tail = currentNodeBefore;  //尾结点变为删除结点的前置结点
                tail.next = header;
            }else {
                currentNodeBefore.next = currentNode.next;
            }
            currentNode.next = null;
        }
        size--;
        return (T) currentNode.data;
    }

    //删除最后一个元素
    public T remove(){
        return delete(size-1);
    }

    /**
     * 尾部插入
     *
     * @param e
     */
    private void linkLast(T e) {
        final Node<T> l = tail;
        final Node<T> newNode = new Node<>(e, null);
        if (l == null) {
            header = newNode;
            tail = header;
        } else {
            tail.next = newNode;   //尾结点指向新结点
            newNode.next = header; //新结点指向头结点
            tail = newNode;        //新结点作为尾结点
        }
        size++;
    }

    private void linkFirst(T e) {
        final Node<T> l = header;
        Node<T> newNode = new Node<>(e, null);
        if (l == null) {
            header = newNode;
            tail = header;
        } else {
            newNode.next = header; //新结点指向header
            header = newNode;      //新结点称为头结点
            tail.next = header;   //尾结点指向头结点
        }
        size++;
    }

    public boolean isEmpty() {
        return size == 0;
    }
    //清空线性表
    public void clear(){
        //将头结点和尾结点设为空
        header = null;
        tail = null;
        size = 0;
    }
    @Override
    public String toString() {
        if (isEmpty())
            return "[]";
        else {
            StringBuilder sb = new StringBuilder("[");
            sb.append(header.data + "->").toString();
            if (header.next != null) {
                for (Node current = header.next; current != header; current = current.next)
                    sb.append(current.data + "->").toString();
            }
            int len = sb.length();
            return sb.delete(len - 2, len).append("]").toString();
        }
    }
}
  • 测试CycleLinkTest
package likend;

/**
 * Created by yxf on 2018/3/27.
 */
public class CycleLinkTest {

    public static void main(String[] args) {
        CycleLink ls = new CycleLink();
        ls.add(2);
        ls.add(4);
        ls.add(5);
        ls.addFirst(1);
        System.out.println("添加元素后的链表为: "+ls);
        ls.insert(2,3);
        System.out.println("在链表位置2插入元素: "+ls);
        ls.delete(2);
        System.out.println("在链表位置2删除元素: "+ls);
        ls.remove();
        System.out.println("删除链表中的一个元素: "+ls);
        System.out.println("获得链表位置为2处的元素:   "+ ls.getElement(2));
        System.out.println("获取元素2的前驱元素:    "+ls.priorElement(2));
        System.out.println("获取元素2的后驱元素:    "+ls.nextElement(2));
        ls.clear();
        System.out.println(ls);
    }
}

测试结果

添加元素后的链表为: [1->2->4->5]
在链表位置2插入元素: [1->2->3->4->5]
在链表位置2删除元素: [1->2->4->5]
删除链表中的一个元素: [1->2->4]
获得链表位置为2处的元素:   4
获取元素2的前驱元素:    1
获取元素2的后驱元素:    4
[]

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/qq_33127597/article/details/79714688