一、什么时双链表
和单链表相比,双链表在每个节点的基础上又新增了一个指针域,指向前驱元素,因为在单链表如果要访问前面一个节点时,需要从头遍历,平均时间复杂度为O(n),而双链表在访问前面一个节点时的时间复杂度为O(1),需要注意的时,双链表在进行插入和删除的时候需要不要忘记还有一个前驱节点需要指向。
双链表在创建时也有所不同需要多一个指针域
typedef struct DNode { //定义双链表的节点类型 ElemType data; //数据 struct DNode *prior,*next; //指针域 }DNode, *DLinkList;
双链表在初始化时也不同代码为
DLinkList InitDLinkList(DLinkList L) { //初始化双链表 DNode *s = (DNode*)malloc(sizeof(DNode)); s->next = NULL; s->prior = NULL; L = s; return L; }
二、双链表的插入和删除
由于除了插入和删除外,其它操作与单链表无异,下面介绍双链表的插入和删除操作。
插入操作:如图所示要注意第一步和第二步必须要在4之前,否则会出现指针丢失情况。
代码如下
Status InsertDLinkList(DLinkList L, int i, ElemType e) { //在表L中第i个位置插入元素e DLinkList p = L; int j = 0; if (i > LengthDLinkList(L)+1||i<0) //如果需要插入节点的位置大于链表大小返回失败代码 return -1; while (j < i -1) { p = p->next; j++; } DNode *newSpace = (DNode*)malloc(sizeof(DNode)); newSpace->data = e; newSpace->next = p->next; if (p->next != NULL) { //如果插入为最后一个节点,不执行下面的步骤 p->next->prior = newSpace; } newSpace->prior = p; p->next = newSpace; return 1; } int LengthDLinkList(DLinkList L) { //返回双链表的长度 int i = 0; DLinkList p = L; while (p->next!= NULL) { p = p->next; i++; } return i; }
删除操作:
代码如下:
Status DeleteElemDLinkList(DLinkList L, int i, ElemType *e) { //删除表中第i个元素,并用e返回其值 DLinkList p = L; DNode *q; int j = 0; if (i > LengthDLinkList(L)||i<0) return -1; while (j < i - 1) { p = p->next; j++; } q = p->next; p->next = q->next; q->next->prior = p; *e = q->data; free(q); return 1; } int LengthDLinkList(DLinkList L) { //返回双链表的长度 int i = 0; DLinkList p = L; while (p->next!= NULL) { p = p->next; i++; } return i; }
如果要看前面讲的单链表请访问https://www.cnblogs.com/bearcanlight/p/13284538.html