单链表中每个结点只有后继结点next 属性,在查找上一个结点的时候,很不方便,我们可以给结点添加 一个指向前驱结点的指针域,使链表进行双方向查找,这种链表就叫做双链表。示意图如下:
结点信息
链表结构示意图:
双链表有两个指针域,所以在插入删除元素的时候,比较麻烦,一个结点要修改两个指针域,而且是有先后顺序的修改。
1.结点的插入操作
假如当前结点为N,在该结点前插入S结点,那么修改指针的时候 需要注意:
S.prev=N.prev
S.next=N
N.prev.next=S
N.prev=S //(该步骤要放最后)
在N结点后插入S结点:
S.prev=N
S.next=N.next
N.next.prev=S
N.next=S //同样放到最后进行
2.结点的删除,假设三个节点顺序为 P,---S,----N
S.prev.next=N
S.next.prev=P
在c#中实现了双向链表,通用链表类LinkedList,不支持索引访问,常用的添加元素方法:
AddAfter:在现有结点后添加新结点
AddBefore:在现有结点前添加新的结点
AddFirst:在开头处添加新的结点
AddLast:在结尾处添加
链表的性能:
优点:1.链表在需要空间的时候才申请,不需要的时候即可释放,有效利用和共享内存空间
2.增删只需要调整相关结点的指针地址,可用于经常增删结点的领域
3.双向链表从两个方向搜索结点,大大简化算法时间复杂度,若其中一条链损坏,仍可使用另一条链操作,并修复受损链
缺点:1.链表算法实现较为复杂抽象,算法实现需要额外的内存空间,以保存结点间的逻辑关系。
2.链表结点只能顺序访问,随机访问性能不佳
3.链表有可能会把结点存放在托管堆的任一角落,这使得强制垃圾回收在处理托管堆中结点对象时需要更多的开销