数据结构学习笔记之用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<Integer> beginMarker;
    private Node<Integer> 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<Integer> it = myl.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

    //构造函数
    public MyLinkedList(){

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

    //建立新节点

    private static class Node<Integer>{

        public Integer data;
        public Node<Integer> prev;
        public Node<Integer> next;

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

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

        } 
    }

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

        beginMarker = new Node<Integer>(null,null,null);
        endMarker = new Node<Integer>(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<Integer> 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<Integer> p,Integer x){

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

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

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

        return p.data;
    }

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

    Node<Integer> p;

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

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

    public Iterator<Integer> iterator(){
        return new LinkedListIterator();
    }

    private class LinkedListIterator implements Iterator<Integer>{

        private Node<Integer> 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++;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值