基本思路:
对于链表没说带傀儡节点或者虚拟节点,这个链表没有真正的头结点,但是我们把第一个节点叫做头结点,它起到标识的作用,标识这个链表的头结点。
这个头结点的位置随时可能发生这变化,是不固定的,之后通过这个头结点我们要完成一些链表的增删查改。如果带傀儡节点这个节点的位置是固定的,那么以后我们操作链表就以这个傀儡节点作为头结点,完成我们的一些基本的增删查改操作。
代码实现:
class ListNode {//建立一个节点 public int val; public ListNode next; public ListNode prev; public ListNode(int val) { this.val = val; } } public class DoubleLinkedList { public ListNode newHead; public ListNode last; public DoubleLinkedList() { this.newHead = new ListNode(-1);虚拟一个傀儡节点 } //计算长度 public int size() { ListNode cur = this.newHead.next; int count = 0; while (cur != null) { count ++; cur = cur.next; } return count; } //打印链表 public void display() { ListNode cur = this.newHead.next; while (cur != null) { System.out.print(cur.val+" "); cur = cur.next; } System.out.println(); } //判断链表中是否有k值 public boolean contains(int key) { ListNode cur = this.newHead.next; while (cur != null) { if (cur.val == key) { return true; } cur = cur.next; } return false; } //头插法 public void addFirst(int data) { ListNode listNode = new ListNode(data); if (this.newHead.next == null) { listNode.prev = this.newHead; this.newHead.next = listNode; this.last = listNode; } else { listNode.next = this.newHead.next; this.newHead.next.prev = listNode; this.newHead.next = listNode; } } //尾插法 public void addLast(int data) { ListNode listNode = new ListNode(data); if (this.newHead.next == null) { this.newHead.next = listNode; this.last = listNode; } else { this.last.next = listNode; listNode.prev = this.last; this.last = listNode; } }
//任意位置插入,第一个数据节点为0号下标 public void addIndex(int index,int data) { ListNode listNode = new ListNode(data); if (index < 0 || index > size()) { System.out.println("该位置不合法!"); return; } if (index == 0) { addFirst(data); return; } if (index == size()) { addLast(data); return; } ListNode cur = findIndex(index); listNode.next = cur; cur.prev.next = listNode; listNode.prev = cur.prev; cur.prev = listNode; } //查找index下标节点 public ListNode findIndex(int index) { ListNode cur = this.newHead.next; while (index != 0) { cur = cur.next; index--; } return cur; }
//删除第一次出现关键字为key的节点 public void remove(int key) { ListNode cur = this.newHead.next; while (cur != null) { if (cur.val == key ) { if (cur == this.newHead.next) { this.newHead.next = this.newHead.next.next; if (this.newHead.next != null) { this.newHead.next.prev = null; }else { this.last = null;//一定不能忘记 否则会发生泄漏 } }else { cur.prev.next = cur.next; if (cur.next != null) { cur.next.prev = cur.prev; }else{ this.last = cur.prev; } } return; }else { cur = cur.next; } } }
//删除所有值为key的节点 public void removeAllKey(int key) { ListNode cur = this.newHead.next; while (cur != null) { if (cur.val == key) { if (cur == this.newHead.next) { this.newHead.next = this.newHead.next.next; if (this.newHead.next != null) { this.newHead.next.prev = null; }else { this.last = null; } }else { cur.prev.next = cur.next; if (cur.next != null) { cur.next.prev = cur.prev; }else{ this.last = cur.prev; } } } cur = cur.next; } } //清空链表 public void clear(){ while (this.newHead.next != null) { ListNode cur = this.newHead.next.next; this.newHead.next.next = null; this.newHead.next.prev = null; this.newHead.next = cur; } this.last = null; } }