双向链表:
在单向链表的deleteFromTail中有一个固有的问题,在删除后一个节点访问前一个节点的时候必须遍历所有节点恰好停在tail前面,对于较长的程序需要访问deleteFromTail函数这是加快速度的一个障碍,为了避免这个问题用了双向链表,双向指针,一个指向前驱一个指向后驱节点,
代码如下:
Template
Class DLLNode{
palic:
DLLNode(){
Next=prev=0;
}
DLLNode(const T& el,DLLNode *n=0,DLLNode *p=0){
Info=el;next=n;prev=p;
}
T info;
DLLNode *next,*prev;
};
Template
Void DoublyLinkedlist::addToDLLTail(const T&el){
If(tail!=0)
{
tail=new DLLNode(el,0,tail);
tail->prev->next=tail;
}
Else head=tail=new=DLLNode(el);
}
Template
T DoubyLinkedListdeleFromDLLTail(){
T el =tail->info;
If(head==tail){
Delete head;
Head =tail=0;
}
Else{
Tail=tail->prev;
Delete tail->next;
Tail->next=0;
}
Return 0;
}
………………
由于多了一个维护的指针,所以要比单向链表要复杂一些。
插入链表操作:
- 创建一个节点,然后初始化三个数据成员
- 将el赋值给info成员
- 将next成员赋值给null
- 将prev成员赋值为tail,使这个成员指向链表中最后一个节点。现在新节点应该是最后一个节点
- 令tail指向新节点。但是无法使用前驱结点访问新节点。
- 令前驱节点的next成员指向新节点。
删除操作:
将临时变量el设置为该节点中保存的值,然后令tail指向前驱节点。在删除最后一个节点。倒数第二个节点next设置成null,最后删除节点中储存的对象。执行从空链表中删除数据会导致崩溃所以应该是用if语句
还有一种是单节点,在这种情况下head和tail都要设置成null。
因为可以立即访问最后一个节点,所以addToDLLTail和deleteFromDLLTail都可以在恒定时间内
很容易得到操作双向链表头节点的函数,只需要将head与tail互换,next和prev互换然后在执行new时交换参数。