数据结构学习笔记之用Java实现双向链表

参考书目《数据结构与算法分析java语言描述—第二版》
要注意头结点和尾节点不包括在链表长度之内!

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyLinkedList {

    private int theSize;
    private int modCount = 0;
    //表示自从构造以来对链表所做改变的次数,指增加或删除节点的次数
    private Node beginMarker;
    private Node endMarker;

    public static void main(String[] args) {

        MyLinkedList myl = new MyLinkedList();

        myl.add(1);
        myl.add(2);
        myl.add(3);
        myl.add(4);
        myl.add(5);
        myl.add(6);
        //1,2,3,4,5,6

        System.out.println(myl.size());
        //打印链表长度6
        //返回链表指定位置上的数据4
        System.out.println(myl.set(3, 10));
        //将链表指定位置上的数据修改,并返回原数据
        //1,2,3,10,5,6

        myl.remove(3);//删除idx=3位置上的节点,即1,2,3,5,6
        Iterator it = myl.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

    //构造函数
    public MyLinkedList(){

    clear();//将链表清空
    }

    //建立新节点

    private static class Node{

        public Integer data;
        public Node prev;
        public Node next;

        public Node(Integer d,Node p,Node n){

        data = d;
        prev = p;
        next = n;

        } 
    }

    //清空链表
    public void clear() {

        beginMarker = new Node(null,null,null);
        endMarker = new Node(null,beginMarker,null);
        beginMarker.next = endMarker;

        theSize = 0;
        modCount++;
    }

    //返回链表的长度
    public int size(){
        return theSize;
    }

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

    //在链表结尾添加新的节点
    public boolean add(Integer x){

        add(size(),x);
        return true;
    }

    //在链表指定位置idx添加新的节点,x是节点的数据值data
    public void add(int idx, Integer x) {

        addBefore(getNode(idx),x);
        //本例中相当于在尾节点之前添加新节点
    }

    //返回链表指定位置的数据
    public Integer get(int idx){
        return getNode(idx).data;
    }

    //修改链表指定位置的数据
    //并返回原数据
    public Integer set(int idx,Integer newVal){

        Node p = getNode(idx);
        Integer oldVal = p.data;
        p.data = newVal;
        return oldVal;
    }

    //删除链表指定位置的节点
    public Integer remove(int idx){
        return remove(getNode(idx));
    }

    //在某个节点之前添加新节点
    private void addBefore(Node p,Integer x){

        Node newNode = new Node(x,p.prev,p);
        newNode.prev.next = newNode;
        p.prev = newNode;
        theSize++;
        modCount++;
    }

    //删除某个节点
    private Integer remove(Node p){

        p.next.prev = p.prev;
        p.prev.next = p.next;
        theSize--;
        modCount++;

        return p.data;
    }

    //返回指定位置idx上的节点
    //注意:size()返回的值不包括头节点和尾节点
    private Node getNode(int idx){

    Node p;

    if(idx<0||idx>size()){
        throw new IndexOutOfBoundsException();
    }

    //折半查找,可以提高查找效率
    if(idx2){
        p = beginMarker.next;
        for(int i = 0;ielse{
        p = endMarker;
        for(int i = size();i>idx;i--){
        p = p.prev;
        } 
    }
    return p; 
}

    public Iterator iterator(){
        return new LinkedListIterator();
    }

    private class LinkedListIterator implements Iterator{

        private Node current = beginMarker.next;
        private int exceptedModCount = modCount;
        private boolean okToRemove = false;

        public boolean hasNext(){

        return current != endMarker;
        //如果current不指向尾节点则继续向后遍历
}

    public Integer next(){

        if(modCount!=exceptedModCount){
    //当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 
            throw new ConcurrentModificationException();
    }

        if(!hasNext()){
            throw new NoSuchElementException();
    }

        Integer nextItem = current.data;
        current = current.next;
        okToRemove = true;
        return nextItem;//返回遍历到的数据
}
    public void remove(){

        if(modCount!=exceptedModCount){
            throw new ConcurrentModificationException();
        }
        if(!okToRemove){
//在非法或不适当的时间调用方法时产生的信号。
//换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。 
            throw new IllegalStateException();
        }

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

你可能感兴趣的:(数据结构)