数据结构 - 单链表

单链表:

简单的链表结构,对象方式实现。通常,单链表实际很少使用,但不失为一个好的学习工具。

没有经过严格的测试,用于学习理解,如有错误,欢迎指正。

复杂度:

头插和尾插:O(1)

中间插入:O(n)

头删:O(1)

尾删:O(n)

中间删:O(n)

按元素删:O(n)

查元素:O(n)

改元素:O(n)

获取长度:O(1)

获取大小:O(1)

  1 package collections;
  2 
  3 import java.util.Iterator;
  4 
  5 public class SingleLinkedList<T> implements Iterable {
  6     private Node<T> head;
  7     private Node<T> cur;
  8     private int len;
  9 
 10     @Override
 11     public Iterator iterator() {
 12         return new SingleLinkedListIterator<>(head);
 13     }
 14 
 15     public SingleLinkedList() {
 16         this.head = new Node<>(null, null);
 17         this.cur = head;
 18         this.len = 0;
 19     }
 20 
 21     /**
 22      * add before
 23      *
 24      * @param var Node{var}
 25      */
 26     public void push(T var) {
 27         head.setNext(new Node<>(var, head.getNext()));
 28         len++;
 29     }
 30 
 31     /**
 32      * add last
 33      *
 34      * @param var Node{var}
 35      */
 36     public void append(T var) {
 37         Node<T> newNode = new Node<>(var, null);
 38         cur.setNext(newNode);
 39         cur = newNode;
 40         len++;
 41     }
 42 
 43     /**
 44      * add element by index
 45      *
 46      * @param index   add position
 47      * @param element element
 48      */
 49     public void insert(int index, T element) {
 50         if (isEmpty() && index == 0) {
 51             push(element);
 52         }
 53         checkIndex(index);
 54         Node<T> lastNode = getLastNode(index);
 55         lastNode.setNext(new Node<>(element, lastNode.getNext()));
 56         len++;
 57     }
 58 
 59     /**
 60      * remove last
 61      */
 62     public void pop() {
 63         if (isEmpty()) {
 64             return;
 65         }
 66         Node<T> lastNode = head;
 67         while (lastNode.getNext().getNext() != null) {
 68             lastNode = lastNode.getNext();
 69         }
 70         lastNode.setNext(null);
 71         cur = lastNode;
 72         len--;
 73     }
 74 
 75     /**
 76      * check index
 77      *
 78      * @param index position
 79      */
 80     private void checkIndex(int index) {
 81         if (index > len - 1 || index < 0) {
 82             throw new ArrayIndexOutOfBoundsException();
 83         }
 84     }
 85 
 86     /**
 87      * get last node by index
 88      *
 89      * @param index current index
 90      * @return last node
 91      */
 92     private Node<T> getLastNode(int index) {
 93         int i = 0;
 94         Node<T> lastNode = head;
 95         while (i++ != index && lastNode.getNext().getNext() != null) {
 96             lastNode = lastNode.getNext();
 97         }
 98         return lastNode;
 99     }
100 
101     /**
102      * remove node by index
103      *
104      * @param index node index from 0 to (length - 1)
105      */
106     public void pop(int index) {
107         checkIndex(index);
108         // left remove
109         if (index == 0) {
110             Node<T> firstNode = head.getNext();
111             head.setNext(firstNode.getNext());
112             firstNode.setNext(null);
113             len--;
114             if (len == 0) {
115                 cur = head;
116             }
117             return;
118         }
119         // right remove
120         if (index == len - 1) {
121             pop();
122             return;
123         }
124         // center remove
125         Node<T> lastNode = getLastNode(index);
126         Node<T> curNode = lastNode.getNext();
127         lastNode.setNext(curNode.getNext());
128         curNode.setNext(null);
129         len--;
130     }
131 
132     /**
133      * remove element by target if existed
134      *
135      * @param target element removed
136      */
137     public void remove(T target) {
138         Node<T> lastNode = head;
139         Node<T> curNode = head;
140         while (curNode != null && curNode.getVar() != target) {
141             lastNode = curNode;
142             curNode = curNode.getNext();
143         }
144         if (curNode == cur) {
145             lastNode.setNext(null);
146             cur = lastNode;
147             len--;
148             return;
149         }
150         if (curNode != null) {
151             lastNode.setNext(curNode.getNext());
152             curNode.setNext(null);
153             len--;
154         }
155     }
156 
157     /**
158      * check element exist
159      *
160      * @param element element checked
161      * @return if exist return index, if not return -1
162      */
163     public int contain(T element) {
164         if (isEmpty()) {
165             return -1;
166         }
167         int i = 0;
168         Node<T> currentNode = head.getNext();
169         while (currentNode.getVar() != element) {
170             currentNode = currentNode.getNext();
171             if (currentNode == null) {
172                 return -1;
173             }
174             i++;
175         }
176         return i;
177     }
178 
179     /**
180      * update element value
181      *
182      * @param index element position
183      * @param element element updated
184      */
185     public void update(int index, T element) {
186         if (isEmpty()) {
187             return;
188         }
189         checkIndex(index);
190         getLastNode(index).getNext().setVar(element);
191     }
192 
193     /**
194      * get length
195      *
196      * @return size of list
197      */
198     public int length() {
199         return len;
200     }
201 
202     /**
203      * check empty
204      *
205      * @return if empty true, else false
206      */
207     public boolean isEmpty() {
208         return len == 0;
209     }
210 
211 }
212 
213 class Node<T> {
214     private T var;
215     private Node<T> next;
216 
217     public Node(T var, Node<T> next) {
218         this.var = var;
219         this.next = next;
220     }
221 
222     public T getVar() {
223         return var;
224     }
225 
226     public void setVar(T var) {
227         this.var = var;
228     }
229 
230     public Node<T> getNext() {
231         return next;
232     }
233 
234     public void setNext(Node<T> next) {
235         this.next = next;
236     }
237 }
238 
239 class SingleLinkedListIterator<T> implements Iterator {
240 
241     private Node<T> cursor;
242 
243     public SingleLinkedListIterator(Node<T> node) {
244         this.cursor = node;
245     }
246 
247     @Override
248     public boolean hasNext() {
249         if (cursor == null) {
250             return false;
251         }
252         boolean flag = cursor.getNext() != null;
253         cursor = cursor.getNext();
254         return flag;
255     }
256 
257     @Override
258     public Object next() {
259         return cursor;
260     }
261 }

 

posted @ 2020-05-09 11:38  御简  阅读(102)  评论(0编辑  收藏  举报