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

这里说的两种双向链表是指带“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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值