手写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的主要内容,如果未能解决你的问题,请参考以下文章

利用Java手写LinkedList

利用Java手写LinkedList

恋上数据结构 链表(手写LinkedList+练习)

从0开始手写ArrayList动态数组和LinkedList双向链表

从0开始手写ArrayList动态数组和LinkedList双向链表

手写数字识别——基于全连接层和MNIST数据集