代码下载:http://stdcpp.cn/downloads/src_code/c/normal/dlist.rar
请使用 VC++6 打开 main.dsw 文件,然后点击运行按钮(就是那个红色的叹号)编译执行。
以下内容为转帖,作者不详。
======================================================
双链表
线性表的插入运算(双向链表存储结构)
在双向循环链表L的位置p处插入一个新元素x的过程Insert可实现如下。

算法:
typedef struct dnode {
elemtype data;
struct dnode *prior, *next;
} DNODE;
int link_ins(DNODE **head, int i, elemtype x)
{
int j = 1; /* 双向循环链表 */
DNODE *p, *q;
q = malloc( sizeof *p );
q->data = x;
if ( i == 0 ) {
q->prior = *head;
q->next = *head;
*head = q;
return 0;
}
p = *head;
j = 0;
while ( ++j < i && p != NULL )
p = p->next;
if ( i < 0 || j < i )
return 1;
else {
q->next = p->next;
p->next = q;
p->next->prior = q;
q->prior = p;
return 0;
}
}
分析:在上面的插入算法中,不需要移动别的元素,但必须
从头开始查找第i结点的地址,一旦找到插入位置,则插入结点
只需两条语句就可完成。该算法的时间复杂度为O(n)
1、双向链表(Doubly Linked List)
双(向)链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域prior。

注意:
①双链表由头指针head惟一确定的。
②带头结点的双链表的某些运算变得方便。
③将头结点和尾结点链接起来,为双(向)循环链表。
2、双向链表的结点结构和形式描述
①结点结构(见上图a)
②形式描述
typedef struct dlistnode {
DataType data;
struct dlistnode *prior,*next;
} DListNode;
typedef DListNode *DLinkList;
DLinkList head;
3、双向链表的前插和删除本结点操作
由于双链表的对称性,在双链表能能方便地完成各种插入、删除操作。
①双链表的前插操作

void DInsertBefore(DListNode *p, DataType x)
{ /* 在带头结点的双链表中,将值为x的新结点插入*p之前,设p≠NULL */
DListNode *s = malloc( sizeof(DListNode) ); /* ① */
s->data = x; /* ② */
s->prior = p->prior; /* ③ */
s->next = p; /* ④ */
p->prior->next = s; /* ⑤ */
p->prior = s; /* ⑥ */
}
②双链表上删除结点*p自身的操作

void DDeleteNode(DListNode *p)
{ /* 在带头结点的双链表中,删除结点*p,设*p为非终端结点 */
p->prior->next = p->next; /* ① */
p->next->prior = p->prior; /* ② */
free(p); /* ③ */
}
注意:
与单链表上的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。
上述两个算法的时间复杂度均为O(1)。
本文乃网上搜集得来,其版权归原作者和原出处所有。如有侵犯版权之处请与我联系,我将马上进行处理。