链表——哨兵
没有哨兵的链表:
ListSearch(L,k) {
x = L.head;
while(x!=null && x.key!=k)
x = x.next;
return x;
}
ListInsert(L,x){
x.next = L.head;
if(L.head!=null)
L.head.pre = x
L.head = x;
x.prev = null;
}
ListDelete(L,x) {
if(x.prev!=null)
x.prev.next = x.next;
else
L.head = x.next;
if(x.next!=null)
x.next.prev = x.prev;
}
存在哨兵的链表:
L.nil便是链表的哨兵
ListSearch(L,k){
x = L.nil.next;
while(x!=L.nil&&x.key!=k)
x = x.next;
return x;
}
ListInsert(L,x){
x.next = L.nil.next;
L.nil.next.prev = x;
L.nil.next = x;
x.prev = L.nil;
}
ListDelete(L,x){
x.prev.next = x.next;
x.next.prev = x.prev;
}
哨兵基本不能降低数据结构相关操作的渐近时间界,但可以降低常数因子。
带哨兵节点的链表,需要额外的一个节点,但插入和删除等操作不需要额外的判断;不带哨兵节点,在处理链表为空时,和其他情况不一样,需要单独判断一次。
带哨兵节点的链表,插入或删除时,不论操作的位置,表头都不变,不需要额外的判断;不带哨兵节点的链表,插入或删除操作发生在第一个节点时,表头指针都要变化,需要额外的处理。