学过集合的读者都知道,ArrayList的底层实现是用数组实现,而LinkedList的实现则是用链表实现。那么什么是链表呢?其实可以把它比喻成一串珠子,珠子通过线来串连起来。要想找到中间的珠子,就只能通过第一个珠子或者最后一个珠子,一个一个的找下去,直到找到所要的珠子。
链表分为单向链表和双向链表,单向链表是指,只能通过前一个珠子找到后一个珠子或者只能通过后一个珠子找到前一个珠子,关联关系是单向的;双向链表是指,既能通过前一个珠子找到后一个珠子,同时也能通过后一个珠子找到前一个珠子,关联关系是双向的。
现在笔者就以双向链表来实现LinkedList。要想通过链表来存放元素,同时还能通过每一个元素来找到下一个或者前一个对象,那么该怎样设计数据结构呢?首先我们将一个珠子当做成一个节点(Node),该节点要实现存放元素(obj),同时还能找到前一个节点(prev)和下一个节点(next),那么我们可以将一个珠子分成三个小块。如图:
根据上面的设计,那么整个双向链表结构就可以描述成如下的图:
这样基本的数据结构我们就定义完成了,接下来就用实际的代码来实现:
1 public class MylinkedList { 2 3 private Node first;//第一个节点 4 private Node last;//最后一个节点 5 private int size; 6 7 //内部类 8 private class Node { 9 Node prev;//前一个节点 10 Object obj;//当前节点的元素 11 Node next;//后一个节点 12 Node(Node prev, Object obj, Node next) { 13 this.prev = prev; 14 this.obj = obj; 15 this.next = next; 16 } 17 18 } 19 20 21 22 public MylinkedList() { 23 } 24 //长度 25 public int size(){ 26 return size; 27 } 28 //空判断 29 public boolean isEmpty(){ 30 return size==0; 31 } 32 //越界判断 33 public void rangeCheck(int index){ 34 if(index<0||index>=size){ 35 try { 36 throw new Exception(); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 } 41 } 42 43 //返回索引处的元素 44 public Node node(int index){ 45 rangeCheck( index); 46 Node temp=first; 47 if(temp!=null){ 48 for(int i=0;i<index;i++){ 49 temp=temp.next;//保证最后一个元素可以取到值 50 } 51 } 52 return temp; 53 } 54 55 //添加最后一个元素 56 public void linkLast(Object obj){ 57 58 Node temp = new Node(last, obj, null); 59 if(first==null){ 60 first=last=temp; 61 }else { 62 last.next=temp;//最后一个元素 63 last=temp; //最后一个元素的节点执向 64 } 65 } 66 67 68 //将元素添加到指定节点 69 public void linkBefore(Object obj,Node node){ 70 Node temp = new Node(null, obj, node); 71 Node up = node.prev; 72 if(up!=null){//存在上一个节点 73 up.next=temp; 74 temp.prev=up; 75 node.prev=temp; 76 }else {//node是第一节点 77 first=temp; 78 } 79 80 } 81 82 83 //添加元素 84 public void add(Object obj){ 85 linkLast(obj); 86 size++; 87 } 88 89 90 //被占领的节点全往后移动 91 public void add(int index,Object obj){ 92 //当index=size时,元素添加到最后一个 93 if(index<0||index>size){ 94 try { 95 throw new Exception(); 96 } catch (Exception e) { 97 e.printStackTrace(); 98 } 99 } 100 if(index==size){ 101 linkLast(obj); 102 }else { 103 linkBefore(obj, node(index)); 104 } 105 size++; 106 } 107 108 109 //获取指定位置的元素 110 public Object get(int index){ 111 rangeCheck(index); 112 Node temp = node(index); 113 return temp.obj; 114 } 115 116 117 118 119 //设置指定位置的元素 120 public void set(int index,Object obj){ 121 rangeCheck(index); 122 Node temp = node(index); 123 temp.obj=obj; 124 } 125 126 127 //返回某一个元素的索引,找到就返回,找不到返回-1 128 public int indexOf(Object obj){ 129 int index=0; 130 for(Node temp =first;temp!=null;){ 131 if(temp.obj.equals(obj)){ 132 return index; 133 } 134 temp= temp.next; 135 index++; 136 } 137 return -1; 138 } 139 140 141 //删除指定元素 142 public void remove(int index){ 143 rangeCheck(index); 144 Node temp = node(index); 145 //获得删除节点的上一个节点和下一个节点 146 Node up = temp.prev; 147 Node down = temp.next; 148 //如果删除的是第一个节点 149 if(up==null){ 150 // down.prev=null; 151 temp=null; 152 first=down; 153 size--; 154 return ; 155 156 } 157 if(down==null){ 158 //up.next=null; 159 temp=null; 160 last=up; 161 size--; 162 return ; 163 164 } 165 up.next=down; 166 down.prev=up; 167 size--; 168 } 169 170 171 172 173 //删除指定元素 174 public void remove(Object obj){ 175 int index=0; 176 for(Node temp =first;temp!=null;){ 177 if(temp.obj.equals(obj)){ 178 temp= temp.next; 179 remove(index); 180 } 181 temp= temp.next; 182 index++; 183 } 184 } 185 186 187 188 189 //清空元素 190 public void clear(){ 191 for(Node temp =first;temp!=null;){ 192 Node next = temp.next; 193 temp.prev=null; 194 temp.obj=null; 195 temp.next=null; 196 temp=next; 197 } 198 size=0; 199 first=last=null; 200 } 201 202 203 204 205 //打印出结果 206 public void Result(){ 207 int i =0; 208 for(Node temp =first;temp!=null;){ 209 Object obj = temp.obj; 210 System.out.println("结果"+i+"= "+obj); 211 temp=temp.next; 212 i++; 213 } 214 } 215 216 217 218 219 public static void main(String[] args) { 220 MylinkedList myLisk = new MylinkedList(); 221 System.out.println("添加元素========"); 222 myLisk.add("lan"); 223 myLisk.add("po"); 224 myLisk.add("zui"); 225 myLisk.add("sha"); 226 myLisk.Result(); 227 System.out.println("指定为添加元素========"); 228 myLisk.add(1, "lu"); 229 myLisk.Result(); 230 System.out.println("获取指定元素========"); 231 Object object = myLisk.get(1); 232 System.out.println(object); 233 System.out.println("设置指定元素========"); 234 myLisk.set(1, "ha"); 235 myLisk.Result(); 236 System.out.println("获取指定元素的索引========"); 237 int indexOf = myLisk.indexOf("zui"); 238 System.out.println(indexOf); 239 System.out.println("根据索引删除指定元素========"); 240 myLisk.remove(1); 241 myLisk.Result(); 242 System.out.println("删除某一个元素========"); 243 myLisk.remove("zui"); 244 myLisk.Result(); 245 System.out.println("清空========"); 246 myLisk.clear(); 247 } 248 249 }
结果如下