手写LinkedList
Posted 谢哥在彼方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写LinkedList相关的知识,希望对你有一定的参考价值。
LinkedList是Java中最为简单也是最为常用的容器之一,那么它的内部构造是什么呢?其实LinkedList的底层实现就是链表,它的各种方法就是对链表进行的一系列操作,例如对链表节点的修改,删除,位移,对链表长度的获取等。我们可以手写一个LinkedList容器,以助我们更好的理解这个容器:
1 package LinkedList; 2 3 import java.util.Iterator; 4 5 public class MyLinkedList<E> implements Iterable<E> { //迭代器接口 6 private Node first; 7 private Node last; 8 private int size; 9 10 public int size() { 11 return size; 12 } 13 14 public void rangeCheck(int index) { 15 if(index<0||index>=size) { 16 try { 17 throw new MyException(); 18 } catch (MyException e) { 19 e.printIndex(); 20 } 21 } 22 } 23 24 public Node node(int index) { //遍历,获得当前位序值 25 if(index<=(size>>1)) { //右移一位相当于除以2 26 Node x = first; 27 for(int i=0;i<index;++i) 28 x=x.next; 29 return x; 30 }else { 31 Node x = last; 32 for(int i=size-1;i>index;--i) 33 x=x.prev; 34 return x; 35 } 36 } 37 38 public boolean isEmpty(){ 39 return size==0; 40 } 41 42 public boolean contains(Object o) { 43 return indexOf(o)>=0; 44 } 45 46 public int indexOf(Object o) { 47 for(int i=0;i<size;++i) { 48 if(node(i).object.equals(o)) 49 return i; 50 } 51 return -1; 52 } 53 54 private Node getNode(int index) { 55 rangeCheck(index); 56 return node(index); 57 } 58 59 @SuppressWarnings("unchecked") 60 private E elementData(int index){ 61 return (E)getNode(index).object; 62 } 63 64 public E get(int index) { 65 return elementData(index); 66 } 67 68 public E set(int index,E element) { 69 rangeCheck(index); 70 E oldValue = elementData(index); 71 node(index).object = element; 72 return oldValue; 73 } 74 75 public void add(E elemnt) { 76 Node n = new Node(); 77 n.object = elemnt; 78 if(first==null) { 79 n.prev = null; 80 n.next = null; 81 first = last = n; 82 }else { 83 last.next = n; 84 n.prev = last; 85 n.next = null; 86 last = n; 87 } 88 ++size; 89 } 90 91 public void add(int index,E element) { 92 Node n = new Node(); 93 n.object = element; 94 if(index>0) { 95 Node temp = getNode(index-1); 96 if(index!=size) 97 temp.next.prev = n; 98 n.next = temp.next; 99 temp.next = n; 100 n.prev = temp; 101 if(index==size) 102 last = n; 103 ++size; 104 }else if(index==0) { 105 if(first==null) { 106 n.prev = null; 107 n.next = null; 108 first = last = n; 109 }else { 110 n.prev = null; 111 n.next = first; 112 first.prev = n; 113 first = n; 114 } 115 ++size; 116 }else { 117 try { 118 throw new MyException(); 119 }catch(MyException e) { 120 e.printIndex(); 121 } 122 } 123 } 124 125 public void remove(int index) { 126 Node temp =getNode(index); 127 if(!(temp==first&&temp==last)) { 128 if(temp==first) { 129 temp.next.prev = null; 130 first = temp.next; 131 }else if(temp==last) { 132 temp.prev.next = null; 133 last = temp.prev; 134 }else { 135 temp.next.prev = temp.prev; 136 temp.prev.next = temp.next; 137 } 138 } 139 temp = null; 140 --size; 141 } 142 143 public boolean remove(E element) { 144 int i = 0; 145 for(Node temp = first;temp!=null;temp=temp.next) { 146 if(temp.object.equals(element)) { 147 remove(i); 148 return true; 149 } 150 ++i; 151 } 152 return false; 153 } 154 155 @Override 156 public Iterator<E> iterator() { 157 return new MyIter(); 158 } 159 160 private class MyIter implements Iterator<E> { 161 162 //计数器-->指针 游标 163 private int cursor; 164 private int lastRet = -1; 165 166 //判断是否存在下一个 167 @Override 168 public boolean hasNext() { 169 return cursor != size; 170 } 171 172 //返回游标当前位置,并把游标移到下一位置 173 @SuppressWarnings("unchecked") 174 @Override 175 public E next() { 176 if(!hasNext()) { 177 try { 178 throw new MyException(); 179 } catch (MyException e) { 180 e.printnext(); 181 } 182 } 183 lastRet = cursor; 184 return (E)node(cursor++).object; 185 } 186 187 @Override 188 public void remove(){ 189 if(lastRet<0) { 190 try { 191 throw new MyException(); 192 } catch (MyException e) { 193 e.printremove(); 194 } 195 } 196 MyLinkedList.this.remove(lastRet); 197 cursor = lastRet; 198 lastRet = -1; 199 } 200 } 201 202 public static void main(String[] args) { 203 MyLinkedList<String> list = new MyLinkedList<>(); 204 list.add("ab"); 205 list.add("cde"); 206 list.add("fghi"); 207 list.add(3,"123"); 208 list.remove(0); 209 //使用迭代器遍历 210 for(Iterator<String> iter=list.iterator();iter.hasNext();){ 211 System.out.println(iter.next()); 212 //iter.remove(); 213 } 214 System.out.println("----------------------------------"); 215 //使用增强for循环遍历 216 for(String str:list){ 217 System.out.println(str); 218 } 219 } 220 } 221 class Node{ 222 Object object; 223 Node prev; 224 Node next; 225 }
1 package LinkedList; 2 3 public class MyException extends Exception{ 4 5 private static final long serialVersionUID = 1L; 6 7 public MyException() { 8 System.out.print("出现异常:"); 9 } 10 11 public void printIndex() { 12 System.out.println("索引范围越界!"); 13 System.exit(1); 14 } 15 16 public void printInit(){ 17 System.out.println("请重新初始化"); 18 } 19 20 public void printnext() { 21 System.out.println("游标越界!"); 22 System.exit(1); 23 } 24 25 public void printremove() { 26 System.out.println("remove()只有在执行完next()后才能且只能执行一次!"); 27 System.exit(1); 28 } 29 }
以上是关于手写LinkedList的主要内容,如果未能解决你的问题,请参考以下文章
从0开始手写ArrayList动态数组和LinkedList双向链表