[数据结构]-单链表

自己写个单链表

package com.cn.jichu.day07;

public class LinkedList<E> {

    private class Node{
        public Node next;
        public E data;

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

        public Node(E data) {
            this(null,data);
        }

        public Node() {
            this(null,null);
        }
    }



    /**
     * 虚拟头节点
     */
    private Node dummyHead;
    /**
     * 当前链表大小
     */
    private int size;

    public LinkedList() {
        dummyHead = new Node();
        size = 0;
    }

    /**
     * 获取链表中有多少个元素
     * @return
     */
    public int getSize(){
        return size;
    }

    /**
     * 判断链表是否为空
     * @return
     */
    public boolean isEmpty(){
        return size == 0;
    }

    /**
     * 在链表的某个位置添加元素
     * @param index
     * @param e
     */
    public void add(int index, E e){
        if(index < 0 || index > size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }

        //找到当前index的前一个节点
        Node prev = dummyHead;
        for(int i = 0;i<index;i++){
            prev = prev.next;
        }
        Node node = new Node(e);
        node.next = prev.next;
        prev.next = node;
        size ++ ;
    }

    /**
     * 向首节点添加元素
     * @param e
     */
    public void addFirst(E e){
        add(0,e);
    }

    /**
     *  向尾节点添加元素
     * @param e
     */
    public void addLast(E e){
        add(size,e);
    }

    /**
     * 获取第index元素
     * @param index
     * @return
     */
    public E get(int index){
        if(index < 0|| index> size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }
        Node cur = dummyHead.next;
        for(int i=0;i<index;i++){
            cur = cur.next;
        }
        return cur.data;
    }

    /**
     * 获取首节点元素
     * @return
     */
    public E getFirst(){
        return get(0);
    }

    /**
     * 获取尾节点元素
     * @return
     */
    public E getLast(){
        return get(size-1);
    }

    /**
     * 删除第index个节点
     * @param index
     * @return
     */
    public E deleteByIndex(int index){
        if(index < 0|| index> size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }
        //定义一个index前的节点,找到index前一个节点
        Node prev = dummyHead;
        for(int i=0;i<index;i++){
            prev = prev.next;
        }
        //定义一个返回去的节点,为前一个节点的下一个节点,就是要删除的当前节点
        Node retNode = prev.next;
        //将前一个节点的next 指向 当前节点的next  将要删除的节点踢出去
        prev.next = retNode.next;
        //要删除的节点还连着 next呢,要将其为null,彻底踢出去,不占用内存 ,要不然一直消耗内存不释放
        retNode.next = null;
        size --;
        return retNode.data;
    }


    /**
     * 删除首节点
     * @return
     */
    public E deleteByFirst(){
       return deleteByIndex(0);
    }

    public E deleteByLast(){
        return deleteByIndex(size-1);
    }

    /**
     * 根据数值删除链表的节点
     * @param data
     * @return
     */
    public void deleteByData(E data){
        Node prev = dummyHead;
        while (prev.next!=null){
            if(prev.next.data.equals(data)){
                break;
            }
            prev = prev.next;
        }
        if(prev.next != null){
            Node delNode = prev.next;
            prev.next = delNode.next;
            delNode.next = null;
        }
    }

    /**
     * 修改第index位置的节点
     * @param index
     * @param e
     */
    public void update(int index,E e){
        if(index < 0|| index> size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }
        Node prev = dummyHead;
        for(int i=0;i<index;i++){
            prev = prev.next;
        }
        prev.next.data = e;
    }

    /**
     * 判断链表中是否有该元素
     * @param e
     */
    public boolean isData(E e){
        boolean ret = false;
        Node node =  dummyHead;
        while (node.next!=null){
            if(node.next.data.equals(e)){
                return true;
            }
            node = node.next;
        }
        return ret;
    }

    /**
     * 链表倒置
     * @param linkedList
     */
    public void reverse(LinkedList linkedList){
        if(linkedList.getSize() == 0){
            throw  new IllegalArgumentException("当前链表为空,请勿倒置");
        }
        Node cur = linkedList.dummyHead.next;
        Node prev = null;
        while (cur!=null){
            Node next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        dummyHead.next = prev;
    }

    /**
     * 查找链表中间节点
     * @return
     */

    public E getMod(LinkedList linkedList){
        if(linkedList.getSize() == 0){
            throw  new IllegalArgumentException("当前链表为空");
        }
        Node slow = linkedList.dummyHead.next;
        Node fast = linkedList.dummyHead.next.next;
        while (fast!=null && fast.next!=null){
            if(!slow.data.equals(fast.data)){
                slow = slow.next;
                fast = fast.next.next;
            }
        }
        return slow.data;
    }


    /**
     * 生成一个环形单链表
     * @return
     */
    public LinkedList  getCircularLinked(LinkedList linkedList,int index){
        if(index < 0|| index> size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }
        Node indexNode = dummyHead.next;
        Node cur = linkedList.dummyHead;;
        for(int i =0;i<index;i++){
            indexNode = indexNode.next;
        }
        while (cur.next!=null){
            cur = cur.next;
        }
        cur.next = indexNode.next;
        return linkedList;
    }



    /**
     * 判断是否是环形链表
     * @return
     */

    public boolean isCircularLinked(LinkedList linkedList){
        boolean ret = false;
        Node slow = linkedList.dummyHead.next;
        Node fast = linkedList.dummyHead.next.next;
        while (fast!=null && fast.next!=null){
            if(slow.equals(fast)){
                ret = true;
                break;
            }else {
                slow = slow.next;
                fast = fast.next;
            }
        }
        return ret;
    }

    /**
     * 删除倒数第N个节点
     * @return
     */
    public LinkedList deleteNthFromEnd(LinkedList linkedList,int index){
        Node first = linkedList.dummyHead.next;
        if(index < 0|| index> size){
            throw  new IllegalArgumentException("大哥,请收回你的非法的index!");
        }
        //1 当index为是当前链表的大小,删除的就是头结点
        if(index == size){
            dummyHead.next = first.next;
            return linkedList;
        }
        //one节点向后移动index位
        Node one = linkedList.dummyHead.next;
        for(int i=0;i<index;i++){
            one = one.next;
        }
        //two节点向后移动一位,one节点向后移动index后与two节点同时向后移动一位,直到one节点到达尾部(one节点比two节点快)
        Node two = linkedList.dummyHead.next;
        while (one.next!=null){
            one = one.next;
            two = two.next;
        }

        two.next = two.next.next;
        return linkedList;
    }


    /**
     * 验证单链表是否是回文链表
     * @return
     */
    public boolean isHuiWen(LinkedList linkedList){
        boolean ret = false;
        //1 先将原链表存储一份新的
        LinkedList<E> newLinkedList = new LinkedList<>();
        Node node = linkedList.dummyHead.next;
        while (node!=null){
            newLinkedList.addLast(node.data);
            node = node.next;
        }

        //2 找到链表的中间节点,慢节点就是从中间节点向后的链表
        Node slow = linkedList.dummyHead.next;
        Node fast = linkedList.dummyHead.next.next;
        while (fast!=null && fast.next!=null){
            slow  = slow.next;
            fast = fast.next.next;
        }


        //3 从中间节点向后的链表进行倒置
        Node cur = slow;
        Node prev = null;
        while (cur!= null){
            Node next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }

        //3 倒置的链表与新的链表进行对比
        Node p = prev;
        Node q = newLinkedList.dummyHead.next;
        // P节点少
        while (p.next!=null){
            if(p.data.equals(q.data)){
                ret = true;
            }else{
                ret = false;
                break;
            }

            p = p.next;
            q = q.next;
        }
        return ret;
    }

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();

        Node cur = dummyHead.next;
        while(cur != null){
            res.append(cur.data + "->");
            cur = cur.next;
        }
        res.append("NULL");

        return res.toString();
    }

}
原文地址:https://www.cnblogs.com/anny0404/p/10649862.html