双链表的简单实现

实现了一个简单难度doubly linked list

  • LinkedList的优点:假定位置是已知的,新项的插入和现有项的删除均开销很小
  • LinkedList的缺点:不容易作索引,对get的调用是很昂贵的
  • 要访问特定元素,只能从链表头开始,遍历到该元素,时间复杂度为 O(n)。
  • 在特定的数据元素之后(前)插入或删除元素,不涉及到其他元素的移动,因此时间复杂度为 O(1)。
MyLinkedList.java
package doppler.List;


public class MyLinkedList<AnyType> implements Iterable<AnyType> {

    private int theSize;
    private int modCount = 0;
    private Node<AnyType> beginMarker;
    private Node<AnyType> endMarker;

    private static class Node<AnyType> {
        public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) {
            data = d;
            prev = p;
            next = n;
        }

        public AnyType data;
        public Node<AnyType> prev;
        public Node<AnyType> next;
    }

    public MyLinkedList() {
        clear();
    }

    public void clear() {
        beginMarker = new Node<AnyType>(null, null, null);
        endMarker = new Node<AnyType>(null, beginMarker, null);
        beginMarker.next = endMarker;

        theSize = 0;
        modCount++;
    }

    public int Size() {
        return theSize;
    }

    public boolean isEmpty() {
        return Size() == 0;
    }

    public boolean add(AnyType x) {
        add(Size(), x);
        return true;
    }

    public void add(int index, AnyType x) {
        addBefore(getNode(index), x);

    }

    public AnyType get(int index){
        return getNode(index).data;
    }

    public AnyType set(int index, AnyType newValue ){
        Node<AnyType> p=getNode(index);
        AnyType oldValue=p.data;
        p.data=newValue;
        return oldValue;
    }

    public AnyType remove(int index){
        return remove(getNode(index));
    }


    private void addBefore(Node<AnyType> p, AnyType x) {
        // 1.将新结点的前驱指向结点p的前驱
        // 2.将新结点的后继指向结点p
        // Node<AnyType> newNode=new Node<AnyType>(x, p.prev, p);
        // 3.将新结点的前驱(也就是结点p原来的前驱)的后继指向新结点
        // newNode.prev.next=newNode;
        // 4.将结点p的前驱指向新结点
        // p.prev=newNode;
        // 可以直接写成一句:
        p.prev = p.prev.next = new Node<AnyType>(x, p.prev, p);

        theSize++;
        modCount++;
    }

    private AnyType remove(Node<AnyType> p) {

        p.prev.next = p.next;
        p.next.prev = p.prev;

        theSize--;
        modCount++;

        return p.data;
    }

    private Node<AnyType> getNode(int index){

        Node<AnyType> p;

        if (index < 0 || index > Size()) {
            throw new IndexOutOfBoundsException();
        }
        if (index < Size()/2 ) {

            p=beginMarker;
            for(int i = 0;i < index; i++){
            p=p.next;   
            }
        } 
        else {
            p=endMarker;
            for(int i = Size();i > index;i--){
                p=p.prev;   
            }
        }

        return p;

    }

    public java.util.Iterator<AnyType> iterator(){
        return new LinkedListIterator();
    }


    private class LinkedListIterator implements java.util.Iterator<AnyType>{

        private Node<AnyType> current = beginMarker;
        private int expectedModConut = modCount;
        private boolean okToRemove = false;

        public boolean hasNext(){
            return current != endMarker;
        }
        public AnyType next(){
            if (modCount != expectedModConut) {
                throw new java.util.ConcurrentModificationException();
            }
            if (!hasNext()) {
                throw new java.util.NoSuchElementException();
            }

            AnyType  nextItem  = current.data;
            current=current.next;
            okToRemove=true;
            return nextItem;
        }

        public void remove(){
            if (modCount != expectedModConut) {
                throw new java.util.ConcurrentModificationException();
            }
            if (!okToRemove) {
                throw new IllegalStateException();
            }

            MyLinkedList.this.remove(current.prev);
            okToRemove = false;
            expectedModConut++;
        }

    }


}
MyLinkedListDemo.java
package doppler.test;

import doppler.List.MyLinkedList;

public class MyLinkedListDemo {

    public static void main(String[] args) {

        MyLinkedList<Integer> myLinkedList=new MyLinkedList<>();
        myLinkedList.add(5);
        myLinkedList.add(4);
        myLinkedList.add(3);
        myLinkedList.add(2);
        myLinkedList.add(1);
        for (Integer integer : myLinkedList) {
            System.out.print(integer+"  ");
        }

        System.out.println();
        myLinkedList.add(9);
        for (Integer integer : myLinkedList) {
            System.out.print(integer+"  ");
        }

        System.out.println();
        myLinkedList.add(3, 6);
        for (Integer integer : myLinkedList) {
            System.out.print(integer+"  ");
        }


        System.out.println();
        myLinkedList.set(0, 6);
        for (Integer integer : myLinkedList) {
            System.out.print(integer+"  ");
        }

        System.out.println();
        myLinkedList.remove(myLinkedList.Size()-1);
        for (Integer integer : myLinkedList) {
            System.out.print(integer+"  ");
        }
        System.out.println();
        System.out.print(myLinkedList.get(myLinkedList.Size()-1));
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值