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

来源:互联网 发布:手机网络挣钱 编辑:程序博客网 时间:2024/05/16 19:22

参考书目《数据结构与算法分析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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快跑,宿主她不对劲 小哭包她软软糯糯 超甜!重生后左相被我撩到腿软 超真实探案推理游戏 惊!霍总怀里的小娇妻失忆后想逃婚 我和暴君有个崽 荒野求生我靠传播非遗爆红全世界 肆意难撩 女尊之夫郎他娇软又呆萌 穿书后,小茶精在疯批怀里撒娇 拯救六界从谈恋爱开始 重生后前世宿敌说要养我 她的沙雕又暴露了 在虐文里绑定了男主系统 我在末世成了领主大人 玄学老祖上综艺后轰动全球了 我继承了老公的神位 仵作掌中娇 世子爷她不可能是女的 穿进红楼后,我成了人生赢家 假死后夫人她称霸黑莲界 奶萌小团宠她觉醒了种田系统 巨星的大佬青梅 总裁的小撩精又生气了 开荒种田:农门辣妻有空间 签到后,小白花她在娱乐圈翻红了 江月照 魂飞魄散的上古大仙在修真界诈尸 快穿:大佬她又抢了反派剧本 夫人她总想逃 穿成阴戾反派未来嫂嫂 上神大人他偏甜系啊 咸鱼后妈带崽在综艺当对照组 系统BUG让我成了舔包专业户 快穿:系统有的是力气和手段 当我的霸总老公有了读心术 穿成炮灰渣妻后我和反派开农场 前任小姐姐帅又飒 弄潮1990从厂长开始 光阴之外 心动侵占