两种双向链表的首项插入与删除效率比较

来源:互联网 发布:java socket 百度云盘 编辑:程序博客网 时间:2024/06/10 06:34

这里说的两种双向链表是指带“sentinel”与不带“sentinel”的,其中带"sentinel"的多了一个"sentinel"节点,以空间换取了时间。两种链表如下图:

1.不带sentinel的:


下面是构造方法以及在首项插入和删除方法,从代码中可以看出没有sentinel的DList在插入时需要处理链表为空的情况,删除的时候需要处理链表为空以及链表只有一个元素的情况,比较麻烦。

public class DList1 {  /**   *  head references the first node.   *  tail references the last node.   */  protected DListNode1 head;  protected DListNode1 tail;  protected long size;    /* DList1 invariants:   *  1)  head.prev == null.   *  2)  tail.next == null.   *  3)  For any DListNode1 x in a DList, if x.next == y and x.next != null,   *      then y.prev == x.   *  4)  For any DListNode1 x in a DList, if x.prev == y and x.prev != null,   *      then y.next == x.   *  5)  The tail can be accessed from the head by a sequence of "next"   *      references.   *  6)  size is the number of DListNode1s that can be accessed from the   *      head by a sequence of "next" references.   */  /**   *  DList1() constructor for an empty DList1.   */  public DList1() {    head = null;    tail = null;    size = 0;  }  /**   *  DList1() constructor for a one-node DList1.   */  public DList1(int a) {    head = new DListNode1();    tail = head;    head.item = a;    size = 1;  }  /**   *  DList1() constructor for a two-node DList1.   */  public DList1(int a, int b) {    head = new DListNode1();    head.item = a;    tail = new DListNode1();    tail.item = b;    head.next = tail;    tail.prev = head;    size = 2;  }  /**   *  insertFront() inserts an item at the front of a DList1.   */  public void insertFront(int i) {  DListNode1 insertItem = new DListNode1(i);  if(head == null){  head = insertItem;  tail = insertItem;  }else{  insertItem.next = head;  head.prev = insertItem;  head = insertItem;  }  size++;  }  /**   *  removeFront() removes the first item (and node) from a DList1.  If the   *  list is empty, do nothing.   */  public void removeFront() {  if(size == 0){  return;  }  if(size == 1){  head = null;  tail = null;  }else{  head.next.prev = null;  head = head.next;  }  size--;  }


2.下边是带sentinel的链表:

下边是构造方法以及首先插入与删除方法,注意构造方法中head的prev和next在链表没有元素的情况下是指向自身的,这一点非常重要,如果设置为null,就失去了这种链表的优势,还需要像第一种链表一样在插入和删除的时候考虑多种情况。

public class DList2 {  /**   *  head references the sentinel node.   *   */  protected DListNode2 head;  protected long size;  /* DList2 invariants:   *  1)  head != null.   *  2)  For any DListNode2 x in a DList2, x.next != null.   *  3)  For any DListNode2 x in a DList2, x.prev != null.   *  4)  For any DListNode2 x in a DList2, if x.next == y, then y.prev == x.   *  5)  For any DListNode2 x in a DList2, if x.prev == y, then y.next == x.   *  6)  size is the number of DListNode2s, NOT COUNTING the sentinel   *      (denoted by "head"), that can be accessed from the sentinel by   *      a sequence of "next" references.   */  /**   *  DList2() constructor for an empty DList2.   */  public DList2() {    head = new DListNode2();    head.item = Integer.MIN_VALUE;    head.next = head;    head.prev = head;    size = 0;  }  /**   *  DList2() constructor for a one-node DList2.   */  public DList2(int a) {    head = new DListNode2();    head.item = Integer.MIN_VALUE;    head.next = new DListNode2();    head.next.item = a;    head.prev = head.next;    head.next.prev = head;    head.prev.next = head;    size = 1;  }  /**   *  DList2() constructor for a two-node DList2.   */  public DList2(int a, int b) {    head = new DListNode2();    head.item = Integer.MIN_VALUE;    head.next = new DListNode2();    head.next.item = a;    head.prev = new DListNode2();    head.prev.item = b;    head.next.prev = head;    head.next.next = head.prev;    head.prev.next = head;    head.prev.prev = head.next;    size = 2;  }  /**   *  insertFront() inserts an item at the front of a DList2.   */  public void insertFront(int i) {  DListNode2 insertItem = new DListNode2(i);  head.next.prev = insertItem;  insertItem.next = head.next;  insertItem.prev = head;  head.next = insertItem;  size++;  }  /**   *  removeFront() removes the first item (and first non-sentinel node) from   *  a DList2.  If the list is empty, do nothing.   */  public void removeFront() {  if(size == 0){  return;  }  DListNode2 remove = head.next;  head.next = remove.next;  remove.next.prev = head;  size--;  }



0 0
原创粉丝点击