链表,其实就是由多个节点组成,而节点就是由存放的值和指针组成。
package linkedList; public class linkedList{ private class Node { private E e; private Node next; public Node(E e, Node next) { this.e = e; this.next = next; } public Node(E e) { this(e, null); } public Node() { this(null, null); } @Override public String toString() { return e.toString(); } } //虚拟头节点(代表头节点的前一个节点-一个不存在的假节点) private Node dummyHead; //元素个数 private int size; public linkedList() { dummyHead = new Node(); size = 0; } // 获取链表中的元素个数 public int getSize() { return size; } // 返回链表是否为空 public boolean isEmpty() { return size == 0; } // 在链表的index(0-based)位置添加新的元素e // 在链表中不是一个常用的操作,练习用:) public void add(int index, E e) { if (index < 0 || index > size) { throw new IllegalArgumentException("index is error"); } //找到index位置的前一个节点 Node prev = dummyHead; for (int i = 0; i < index; i++) { prev = prev.next; } Node next = prev.next; prev.next = new Node(e, next); size++; } // 在链表头添加新的元素e public void addFirst(E e) { add(0, e); } // 在链表末尾添加新的元素e public void addLast(E e) { add(size, e); } // 获得链表的第index(0-based)个位置的元 public E get(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException("index is error"); } Node cur = dummyHead; for (int i = 0; i <= index; i++) { cur = cur.next; } return cur.e; } // 获得链表的第一个元素 public E getFirst() { return get(0); } // 获得链表的最后一个元素 public E getLast() { return get(size - 1); } // 修改链表的第index(0-based)个位置的元素为e public void set(int index, E e) { if (index < 0 || index >= size) { throw new IllegalArgumentException("index is error"); } Node cur = dummyHead; for (int i = 0; i <= index; i++) { cur = cur.next; } cur.e = e; } // 查找链表中是否有元素e public boolean contains(E e) { Node cur = dummyHead.next; while (cur != null) { if (cur.e.equals(e)) { return true; } cur = cur.next; } return false; } // 从链表中删除index(0-based)位置的元素, 返回删除的元素 // 在链表中不是一个常用的操作,练习用:) public E remove(int index) { if (index < 0 || index >= size) { throw new IllegalArgumentException("index is error"); } Node prev = dummyHead; for (int i = 0; i < index; i++) { prev = prev.next; } Node removeNode = prev.next; prev.next = removeNode.next; removeNode.next = null; size--; return removeNode.e; } // 从链表中删除第一个元素, 返回删除的元素 public E removeFirst() { return remove(0); } // 从链表中删除最后一个元素, 返回删除的元素 public E removeLast() { return remove(size - 1); } // 从链表中删除元素e public void removeElement(E e) { Node prev = dummyHead; while(prev.next != null){ if(prev.next.e.equals(e)){ Node delNode = prev.next; prev.next = delNode.next; delNode.next = null; size --; }else { prev = prev.next; } } } @Override public String toString() { StringBuilder res = new StringBuilder(); Node cur = dummyHead.next; while(cur != null){ res.append(cur + "->"); cur = cur.next; } res.append("NULL"); return res.toString(); } }
在上一章介绍了栈和队列,基于数组实现。 这里使用链表也可以实现:
栈:
public class linkedListStackimplements Stack { private linkedList linkedList; public linkedListStack(){ linkedList = new linkedList (); } @Override public int getSize() { return linkedList.getSize(); } @Override public boolean isEmpty() { return linkedList.isEmpty(); } @Override public void push(E e) { linkedList.addFirst(e); } @Override public E pop() { return linkedList.removeFirst(); } @Override public E peek() { return linkedList.getFirst(); } }
也可以使用addLast(),removeLast(); 但是需要从头遍历到最后一个元素,时间复杂度变成了O(n)
队列:
public class linkedListQueueimplements Queue { private linkedList linkedList; public linkedListQueue(){ linkedList = new linkedList (); } @Override public int getSize() { return linkedList.getSize(); } @Override public boolean isEmpty() { return linkedList.isEmpty(); } @Override public void enqueue(E e) { linkedList.addLast(e); } @Override public E dequeue() { return linkedList.removeFirst(); } @Override public E getFront() { return linkedList.getFirst(); } }
如上,删除的时间复杂度是O(1),添加的时间复杂度是O(n),因为需要从头遍历到最后一个元素,才知道添加的位置在哪里。 如果使用addFirst()和removeLast(),复杂度就反过来了。
如果底层链表的实现,不仅记录了头节点的位置,也记录了尾节点的位置,那么添加和删除都会变为O(1):
public class linkedListTailQueueimplements Queue { private class Node { private E e; private Node next; public Node(E e, Node next) { this.e = e; this.next = next; } public Node(E e) { this(e, null); } public Node() { this(null, null); } @Override public String toString() { return e.toString(); } } //头节点 private Node head; //尾节点 private Node tail; private int size; public linkedListTailQueue() { head = null; tail = null; size = 0; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size==0; } @Override public void enqueue(E e) { if(tail == null){ tail = new Node(e); head = tail; }else { tail.next = new Node(e); tail = tail.next; } size++; } @Override public E dequeue() { if(isEmpty()) { throw new IllegalArgumentException("Cannot dequeue from an empty queue."); } Node removeNode = head; head = head.next; removeNode.next = null; size--; if(head == null){ tail = null; } return removeNode.e; } @Override public E getFront() { if(isEmpty()) { throw new IllegalArgumentException("Cannot get from an empty queue."); } return head.e; } }



