欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java实现带头结点的单链表、不带头结点单链表、不带头单向循环链表、不带头双向链表的增删改查操作

程序员文章站 2022-03-15 17:30:20
...

带头结点的单链表

public class Entry<T extends Comparable<T>> {//自定义数据类型才需要重写compareTo方法
    private T value;
    private Entry<T> next;
    public Entry(){//头结点

    }
    public Entry(T value){//其他结点
        this.value = value;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    public Entry<T> getNext() {
        return next;
    }

    public void setNext(Entry<T> next) {
        this.next = next;
    }
}

public class SingleLink<E extends Comparable<E>>{//带头结点
    private Entry<E> head;
    private Entry<E> tail;//想让时间复杂度降低,防止遍历导致时间复杂度大

    public SingleLink(){
        head = new Entry<>();
        tail = head;
    }

    public void addHead(E value){
        Entry<E> newEntry = new Entry<>(value);
        newEntry.setNext(head.getNext());
        head.setNext(newEntry);
    }
    public void addTail(E value){//时间复杂度可以达到O(1)
        Entry<E> newEntry = new Entry<>(value);
        tail.setNext(newEntry);
        tail = newEntry;//更新尾节点
    }
    public void deleteHead(){
        if(head.getNext()==null){//防止空指针异常
            return;
        }
        Entry<E> p=head.getNext();
        head.setNext(head.getNext().getNext());
//        防止内存泄漏
        p.setValue(null);
        p.setNext(null);
    }
    public void deleteTail(){//时间复杂度为O(n),无法达到O(1)
        Entry<E> p=head;
        if(p.getNext()==null){
            return;
        }
        while(p.getNext().getNext()!=null){
            p=p.getNext();
        }
        p.setNext(null);
        //防止内存泄漏
        p.getNext().setValue(null);
        /**
         * TODO:再次遍历,更新尾节点(这一步我没有写出来)
         */
    }
    public void deleteValue(E value){
        Entry<E> p=head;
        for(;p.getNext()!=null;p=p.getNext()){
            if (p.getNext().getValue().compareTo(value)==0){//不建议用equals,假如传的是People类型(自定义数据类型),可能忘记重写equals方法
                break;
            }
        }
        Entry<E> q=p.getNext();
        p.setNext(p.getNext().getNext());
        //防止内存泄漏
        q.setValue(null);
        q.setNext(null);
    }
}

不带头结点的单链表

public class SingleLinkNoHead<T extends Comparable<T>> {
    public static class Entry<E extends Comparable<E>> {//改成public易于测试
        public E value;
        public Entry<E> next;

        public Entry(E value) {
            this.value = value;
        }

        public void setNext(Entry<E> next) {
            this.next = next;
        }

        public E getValue() {
            return value;
        }

        public void setValue(E value) {
            this.value = value;
        }

        public Entry<E> getNext() {
            return next;
        }
    }

    private Entry<T> headEntry;
    private Entry<T> tailEntry;
    
    public SingleLinkNoHead() {

    }

public void addHead(T value) {
    Entry<T> newEntry = new Entry<>(value);
    if (headEntry == null) {
        headEntry = newEntry;
        tailEntry = newEntry;
    } else {
        newEntry.next = headEntry;
        headEntry = newEntry;
    }
}

public void addTail(T value) {
    Entry<T> newEntry = new Entry<>(value);
    if (headEntry == null) {
        headEntry = newEntry;
        tailEntry = newEntry;
    } else {
        tailEntry.next = newEntry;
        tailEntry = newEntry;
    }
}

public void deleteHead() {
    if (headEntry == null) {
        return;
    } else if (headEntry.next == null) {
        headEntry = null;
        tailEntry = null;
    } else {
        Entry<T> p = headEntry;
        headEntry = headEntry.next;
        p.value = null;
        p.next = null;
    }
}

private Entry<T> searchPrio() {//找尾节点前驱
    for (Entry<T> p = headEntry; p != null; p = p.next) {
        if (p.next == tailEntry) {
            return p;
        }
    }
    return null;
}

public void deleteTail() {
    Entry<T> prio = searchPrio();
    if (prio == null) {
        return;
    } else if (headEntry.next == null) {
        headEntry.value = null;
        headEntry = null;
        tailEntry = null;
    } else {
        prio.next = null;
        tailEntry.value = null;
        tailEntry = prio;
    }
}

不带头结点的单向循环链表

public class CircleSingleLink<T> {
    private static class Entry<E> {
        private Entry<E> next;
        private E value;

        public Entry(E value) {
            this.value = value;
            next = this;
        }
    }

    private Entry<T> headEntry;
    private Entry<T> tailEntry;

    public CircleSingleLink() {
    }

    public void addHead(T value) {
        Entry<T> newEntry = new Entry<>(value);
        if (headEntry == null) {
            headEntry = newEntry;
            tailEntry = newEntry;
        } else {
            //1
            newEntry.next = headEntry;
            //2
            headEntry = newEntry;
            //3
            tailEntry.next = headEntry;
        }
    }

    public void addTail(T value) {
        Entry<T> newEntry = new Entry<>(value);
        if (headEntry == null) {
            headEntry = newEntry;
            tailEntry = newEntry;
        } else {
            tailEntry.next = newEntry;
            newEntry.next = headEntry;
            tailEntry = newEntry;
        }
    }

    public void deleteHead() {
        if (headEntry == null)
            return;
        //防止内存泄漏
        headEntry.value = null;
        //只有一个节点
        if (headEntry.next == headEntry) {
            headEntry = null;
            tailEntry = null;
        } else {
            tailEntry.next = headEntry.next;
            headEntry = headEntry.next;
        }
    }

    public void deleteTail() {
        if (headEntry == null) {
            return;
        } else if (headEntry.next == headEntry) {
            headEntry = null;
            tailEntry = null;
        } else {
            Entry<T> p = headEntry;
            for (; p != null; p = p.next) {
                if (p.next == tailEntry) {
                    break;
                }
            }
            p.next = headEntry;
            tailEntry.next = null;
            tailEntry.value = null;
            tailEntry = p;
        }
    }
}

不带头结点的双向链表

public class DoubleLink<T> {
    public static class Entry<E> {
        private E value;
        private Entry<E> next;
        private Entry<E> prev;

        public Entry(E value) {
            this.value = value;
        }
    }

    private Entry<T> headEntry;
    private Entry<T> tailEntry;

    public DoubleLink() {

    }

    public void addHead(T value) {
        Entry<T> newEntry = new Entry<>(value);
        if (headEntry == null) {
            headEntry = newEntry;
            tailEntry = newEntry;
        } else {
            newEntry.next = headEntry;
            headEntry.prev = newEntry;
            headEntry = newEntry;
        }
    }

    public void addTail(T value) {
        Entry<T> newEntry = new Entry<>(value);
        if (headEntry == null) {
            headEntry = newEntry;
            tailEntry = newEntry;
        } else {
            tailEntry.next = newEntry;
            newEntry.prev = tailEntry;
            tailEntry = newEntry;
        }
    }

    public void deleteHead() {
        if (headEntry == null) {
            return;
        } else if (headEntry.next == null) {
            headEntry = null;
            tailEntry = null;
        } else {
            headEntry.value = null;
            headEntry.next.prev = null;
            headEntry = headEntry.next;
        }
    }

    public void deleteTail() {
        if (headEntry == null) {
            return;
        } else if (headEntry.next == null) {
            headEntry = null;
            tailEntry = null;
        } else {
            Entry<T> p =headEntry;
           for(;p!=null;p=p.next){
               if(p.next==tailEntry){
                   break;
               }
           }
            p.next=null;
            tailEntry.value=null;
            tailEntry.prev=null;
            tailEntry=p;
        }
    }
}