自己用java实现LinkList和arrayList
来源:互联网 发布:linux 自动启动svn 编辑:程序博客网 时间:2024/06/05 02:08
为了加深理解,我就自己写了下LinkList和arrayList。
下面贴下代码
链表代码public class MyTwoLinkedList<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 AnyType data; public Node<AnyType> prev; public Node<AnyType> next; public Node(AnyType d, Node<AnyType> p, Node<AnyType> n) { data = d; prev = p; next = n; } } public MyTwoLinkedList() { 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 add(AnyType x) { add(size(), x); return true; } public void add(int idx, AnyType x) { addBefore(getNode(idx), x); } //搜索节点,先判断节点在前半段还是后半段,略提高效率,双链表可以从两个方向查找 private Node<AnyType> getNode(int idx) { Node<AnyType> 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; } private void addBefore(Node<AnyType> p, AnyType x) { Node<AnyType> newNode = new Node<AnyType>(x, p.prev, p);//双链表,新增节点插入指向前后 //前后两个节点的指向变化 newNode.prev.next = newNode; p.prev = newNode; theSize++; //修改次数+1 modCount++; } public AnyType get(int idx) { return getNode(idx).data; } public AnyType set(int idx, AnyType newVal) { //一个引用,改变节点值 Node<AnyType> p = getNode(idx); AnyType oldVal = p.data; p.data = newVal; return oldVal; } public AnyType remove(int idx) { return remove(getNode(idx)); } private AnyType remove(Node<AnyType> p) { p.next.prev = p.prev; p.prev.next = p.next; theSize--; //修改次数仍+1 modCount++; return p.data; } public java.util.Iterator<AnyType> iterator() { //返回一个实例化的内部类,该类是迭代器,内部实现 return new MyTwoLinkedList.LinkedListIterator(); } //实现Iterator接口 private class LinkedListIterator implements java.util.Iterator<AnyType> { //在内部指向第一个元素 private Node<AnyType> current = beginMarker.next; //检测在迭代期间集合被修改的情况,分别在next()和迭代器自己的remove()中检查,如果修改次数不同说明在迭代器迭代之外发生了修改行为 //迭代器自己的remove()调用外层类的remove,其中有modCount++,迭代器做出remove()动作后将expectecModCount++,保证迭代期间二者保持一致 private int expectedModCount = modCount; //okToRemove在next()执行后被置为true,在迭代器自己的remove()执行完后置为false,迭代器自己的remove()执行前检查其是否为true才执行,保证迭代一次才能删除一个,没有其他迭代时删除的方式 private boolean okToRemove = false; public boolean hasNext() { return current != endMarker; } public AnyType next() { if (modCount != expectedModCount) //同一时间修改冲突异常!! 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 != expectedModCount) throw new java.util.ConcurrentModificationException(); //不是迭代期间调用此迭代器remove()方法 if (!okToRemove) throw new IllegalStateException(); //调用外部类方法 //next()使current先指向下一元素,这里移除current前一个元素,这样边迭代边移除,先后移后删除前一个元素 MyTwoLinkedList.this.remove(current.prev); okToRemove = false; expectedModCount++; } }}
双链表头尾放置两个值为null的Node对象,这样使头尾节点的处理也正常化,不会是删除头尾元素成为特别的情况存在。双链表还有就是每个节点存储上下两个节点的信息。删除的开销,在链表来,只是修改删除元素首尾节点的指向而已。而且由于是双链表可以从两端开始遍历,这样,用getNode方法,确认元素是在哪个半段。这样能用最快的速度来遍历。后面的迭代器实现,主要是用modcount参数,来保证链表的一致性的。
ArrayList代码public class MyTestArrayList<AnyType> implements Iterable<AnyType> { // //默认容器 private static final int DEFAULT_CAPACITY = 10; private int theSize; private AnyType[] theItems; public MyTestArrayList() { clear(); } public void clear() { theSize = 0; ensureCapacity(DEFAULT_CAPACITY); } public void ensureCapacity(int newCapacity) { if (newCapacity < theSize) { return; } AnyType[] old = theItems; theItems = (AnyType[]) new Object[newCapacity]; for (int i = 0; i < size(); i++) { theItems[i] = old[i]; } } public Boolean add(AnyType x) { add(size(), x); return true; } public void add(int idx, AnyType x) { if (idx > size()) { throw new IndexOutOfBoundsException("Index:" + idx + " Size :" + size()); } if (theItems.length == size()) ensureCapacity(size() * 2); for (int i = theSize; i > idx; i--) theItems[i] = theItems[i - 1]; theItems[idx] = x; theSize++; } public AnyType get(int idx) { if (idx < 0 || idx > size()) throw new ArrayIndexOutOfBoundsException(); return theItems[idx]; } public AnyType set(int idx, AnyType x) { if (idx < 0 || idx > size()) throw new ArrayIndexOutOfBoundsException(); AnyType oldValue = theItems[idx]; theItems[idx] = x; return oldValue; } public Boolean isEmpty() { return size() == 0; } public int size() { return theSize; } public AnyType remove(int idx) { AnyType deleteItem = theItems[idx]; for (int i = idx; i < size() - 1; i++) { theItems[i] = theItems[i + 1]; }// theSize--; theItems[--theSize] = null; return deleteItem; } public java.util.Iterator<AnyType> iterator(){ return new ArrayListIterator(); } public class ArrayListIterator implements java.util.Iterator<AnyType> { private int current = 0; public boolean hasNext() { return current < size(); } public AnyType next(){ if(!hasNext()) throw new java.util.NoSuchElementException(); return theItems[current++]; } public void remove(){ //MyArraList.this代表外层类MyArrayList的对象 //--current这里暂解释为remove在next方法后调用,next让current++, //这里让current回到原来位置,删除它 //因为如果不调用next直接remove,current会出现<0情况 MyTestArrayList.this.remove(--current); } }}
数组相较于上面的链表感觉删除就比较坑了,毕竟不知道要删除哪个元素。如果删除头元素,那么整个数组都要进行一次循环赋值,很坑的。其他的两者基本上都有点类似了。
阅读全文
0 0
- 自己用java实现LinkList和arrayList
- java中ArrayList和LinkList的区别
- java中ArrayList和LinkList的区别
- java集合之ArrayList和LinkList
- 【java笔试系列三】ArrayList和LinkList
- 【java笔试系列三】ArrayList和LinkList
- java基础三:Arraylist和LinkList区别
- LinkList 和 ArrayList 测试
- ArrayList和LinkList剖析
- linklist和arraylist
- JAVA--自己实现ArrayList
- java中ArrayList 、LinkList区别
- java中ArrayList 、LinkList区别
- java之List ArrayList LinkList
- java中ArrayList 、LinkList区别
- Java中ArrayList 、LinkList区别
- java中ArrayList 、LinkList区别
- java中ArrayList 、LinkList区别
- js parseInt和map函数
- RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
- 大盘指数三连阴后强势反弹 周期性板块该不该追?
- 查看当前网卡用的是哪个phy
- hdu1274 展开字符串(C语言)
- 自己用java实现LinkList和arrayList
- Java多线程基础知识回顾与总结
- jstack Dump 日志文件中的线程状态
- 1013. Battle Over Cities (25)(并查集/dfs)
- 基于servlet/jsp+mysql(DbUtils )的学生系统
- 关于集合
- VS2013+OpenCV2.4.10永久配置
- HBase查找一条数据的过程
- PyBOMBS安装GNURadio