链表增删查改,插入,排序,反转,从左到右或从右到左遍历

java版链表增删查改,插入,排序,反转,从左到右或从右到左遍历

演示代码:

package linklist;

public class Main {
    public static void main(String[] args) {
        LinkList<String> linkList = new LinkList<>();
        linkList.add("a");
        linkList.add("c");
        linkList.add("b");
        linkList.add(null);
        linkList.add("e");
        linkList.add("d");
        linkList.add(null);
        System.out.println(linkList.size());
        System.out.println(linkList);
        linkList.reverse();
        System.out.println(linkList);
        linkList.sort(String::compareTo);
        System.out.println(linkList);

        LinkList<Integer> linkList1 = LinkList.fromArray(4, 6, 6, 5, 9);
        linkList1.sort(Integer::compareTo);
        System.out.println(linkList1);
        linkList1.reverse();
        System.out.println(linkList1);

        LinkList<String> linkList2 = LinkList.fromArray("a", "d", "b");
        System.out.println(linkList2);
        linkList2.insert(1, "c");
        System.out.println(linkList2);
        linkList2.insert(0, "e");
        System.out.println(linkList2);

        System.out.println(linkList2.get(1));
        System.out.println(linkList2.set(1, "-"));
        System.out.println(linkList2.get(1));
        linkList2.remove(1);
        System.out.println(linkList2);

        linkList2.forEach(System.out::println);
        System.out.println("------");
        linkList2.forEachFromRight(System.out::println);
    }
}

实现代码:

package linklist;

import com.sun.istack.internal.NotNull;

import java.util.Comparator;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class LinkList<T> {
    public static class Node<T> {
        T data;
        Node prev;
        Node next;

        public Node() {
        }

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

    private final int TO_STRING_MAX_COUNT = 1000;

    private Node head = null;

    private Node tail = null;

    private long size;

    public void add(T data) {
        if(size == Long.MAX_VALUE) {
            throw new OutOfMemoryError();
        }

        if (head == null) {
            tail = head = new Node();
        }

        Node newNode = new Node(data, head, null);
        tail.next = newNode;
        newNode.prev = tail;
        tail = newNode;
        size = size + 1;
    }

    public void insert(long index, T data) {
        if (index < 0) {
            throw new IndexOutOfBoundsException(String.format("Size: %d, Index: %d", size, index));
        }

        if (index >= size) {
            add(data);
            return;
        }

        Node pre = head;
        long i = 0;
        while (i < index) {
            pre = pre.next;
            i = i + 1;
        }
        Node preNext = pre.next;
        pre.next = new Node(data, pre, preNext);
        preNext.prev = pre.next;
    }

    public T set(long index, T data) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException(String.format("Size: %d, Index: %d", size, index));
        }

        Node<T> curent = head.next;
        long i = 0;
        while (i < index) {
            curent = curent.next;
            i = i + 1;
        }
        T old = curent.data;
        curent.data = data;
        return old;
    }

    public T get(long index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException(String.format("Size: %d, Index: %d", size, index));
        }

        Node<T> curent = head.next;
        long i = 0;
        while (i < index) {
            curent = curent.next;
            i = i + 1;
        }
        return curent.data;
    }

    public boolean remove(long index) {
        if (head == null) {
            return false;
        }

        Node current = head.next;
        long i = 0;
        while (current != null) {
            if (i == index) {
                if (current == tail) {
                    tail = current.prev;
                    tail.next = null;
                } else {
                    current.next.prev = current.prev;
                    current.prev.next = current.next;
                }

                current.prev = null;
                current.next = null;
                current.data = null;
                --size;
                return true;
            }
            current = current.next;
            i = i + 1;
        }
        return false;
    }

    public boolean remove(T data) {
        if (head == null) {
            return false;
        }

        Node current = head.next;
        while (current != null) {
            if (Objects.equals(current.data, data)) {
                if (current == tail) {
                    tail = current.prev;
                    tail.next = null;
                } else {
                    current.next.prev = current.prev;
                    current.prev.next = current.next;
                }

                current.prev = null;
                current.next = null;
                current.data = null;
                size = size - 1;
                return true;
            }
            current = current.next;
        }
        return false;
    }

    public boolean find(T data) {
        if (head == null) {
            return false;
        }

        Node current = head.next;
        while (current != null) {
            if (Objects.equals(current.data, data)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    public void reverse() {
        if (head == null) {
            return;
        }

        Node temp = null;
        Node current = head.next;
        while (current != null) {
            Node currentNext = current.next;
            if (temp == null) {
                temp = current;
                temp.next = null;
                tail = temp;
            } else {
                current.next = temp;
                temp.prev = current;
                temp = current;
            }
            current = currentNext;
        }
        head.next = temp;
    }

    public void sort(@NotNull Comparator<T> comparator) {
        if (comparator == null) {
            throw new NullPointerException("comparator for sort required not null");
        }

        if (size < 2) {
            return;
        }

        Node<T> sorted = head.next;
        Node<T> current = head.next.next;
        sorted.next = null;
        while (current != null) {
            Node<T> currentNext = current.next;
            Node<T> sortedCurrent = sorted;
            Node<T> pre = head;
            while (sortedCurrent != null) {

                if (current == sortedCurrent) {
                    continue;
                }

                int cp;
                if (sortedCurrent.data == null || current.data == null) {
                    if (sortedCurrent.data == null) {
                        cp = -1;
                    } else {
                        cp = 1;
                    }
                } else {
                    cp = comparator.compare(current.data, sortedCurrent.data);
                }

                if (cp <= 0) {
                    pre.next = current;
                    current.prev = pre;
                    current.next = sortedCurrent;
                    sorted = head.next;
                    break;
                } else if (sortedCurrent.next == null) {
                    sortedCurrent.next = current;
                    current.prev = sortedCurrent;
                    current.next = null;
                    break;
                }

                pre = sortedCurrent;
                sortedCurrent = sortedCurrent.next;
            }
            current = currentNext;
        }
    }

    public void forEach(Consumer<? super T> action) {
        Node<T> current = head.next;
        while (current != null) {
            action.accept(current.data);
            current = current.next;
        }
    }

    public void forEachFromRight(Consumer<? super T> action) {
        Node<T> current = tail;
        while (current != head) {
            action.accept(current.data);
            current = current.prev;
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        if (head == null) {
            sb.append("[]");
        } else {
            boolean showAll = true;
            long count = 0;
            sb.append("[");
            Node current = head.next;
            while (current != null) {
                if (current.data == null) {
                    sb.append("null, ");
                } else {
                    sb.append(current.data.toString()).append(", ");
                }
                current = current.next;
                if (++count == TO_STRING_MAX_COUNT) {
                    showAll = false;
                    break;
                }
            }
            sb.delete(sb.length() - 2, sb.length());
            if (!showAll) {
                sb.append(", ...");
            }
            sb.append("]");
        }
        return sb.toString();
    }

    public long size() {
        return size;
    }

    public static <T> LinkList<T> fromArray(T... arr) {
        if (arr == null || arr.length == 0) {
            return new LinkList<>();
        }

        LinkList<T> linkList = new LinkList<>();
        Stream.of(arr).forEach(linkList::add);
        return linkList;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值