实现链表
首先我们创建一个链表的基本结构,这个类具有一个私有的Node内部类,之所以设置成私有是为了向外隐藏细节,Node里面则存在一个对象和一个Node节点,这个Node节点就是当前节点的下一个节点,利用这种结构就可以将Node像链条一样链接起来
public class LinkedList<E> { private class Node{ public E e; public 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; } }
接下来实现链表的添加操作,也就是add方法
//在链表的某个节点处插入新节点 public void add(int index, E e){ if(index < 0 || index > size) throw new IllegalArgumentException("index不合法."); Node prev = dummyHead; for(int i = 0 ; i < index ; i ++) prev = prev.next; prev.next = new Node(e, prev.next); size ++; }
复用add方法可以实现向链表头尾插入节点的方法
// 在链表头添加新的元素e public void addFirst(E e){ add(0, e); } // 在链表末尾添加新的元素e public void addLast(E e){ add(size, e); }
实现获取某个节点内对象的方法,也就是get方法
public E get(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("index不合法."); Node cur = dummyHead.next; for(int i = 0 ; i < index ; i ++) cur = cur.next; return cur.e; }
复用get方法可以实现获取头尾节点的对象的方法
// 获得链表的第一个元素 public E getFirst(){ return get(0); } // 获得链表的最后一个元素 public E getLast(){ return get(size - 1); }
实现set方法,把对象设置到某个节点内
public void set(int index, E e){ if(index < 0 || index >= size) throw new IllegalArgumentException("Set failed. Illegal index."); Node cur = dummyHead.next; for(int i = 0 ; i < index ; i ++) cur = cur.next; cur.e = e; }
实现contains方法,查看链表是否包含某元素
// 查找链表中是否有元素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; }
实现remove方法,只要找到待删除节点的前一个节点,然后把前节点指向待删除节点的下一个节点,最后把待删除节点的next置空让jvm回收即可
public E remove(int index){ if(index < 0 || index >= size) throw new IllegalArgumentException("index不合法."); Node prev = dummyHead; for(int i = 0 ; i < index ; i ++) prev = prev.next; Node retNode = prev.next; prev.next = retNode.next; retNode.next = null; size --; return retNode.e; }
实现完链表以后我们可以发现,链表这个结构在只对头节点操作的时候效率很高,而这个特性非常契合栈,所以我们可以用链表实现栈,具体在