单链表vs双链表–初篇
单链表对于某一结点前面的区域是未知的。即无法逆向检索,有时候不太方便
双链表则可以逆向检索,但是存储密度相比较稍微低一点。
双链表
初始化(带头结点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| typedef struct DNode { Elemtype data; struct DNode* prior, * next; }DNode,*DLinklist;
bool InitDLinklist(DLinklist& L) { L = (DNode*)malloc(sizeof(DNode)); if (L == NULL) return false; L->prior = NULL; L->next = NULL; return true; } void testDLinklist() { DLinklist L; InitDLinklist(L); }
bool Empty(DLinklist L){ if(L->next==NULL) return true; else return false; }
|
插入
修改指针时注意顺序
1 2 3 4 5 6 7 8 9 10 11
| bool InsertNextDNode(DNode* p, DNode* s) { if (p==NULL||s==NULL) return false; s->next = p->next; if (p->next != NULL) p->next->prior = s; s->prior = p; p->next = s; return true; }
|
删除
1 2 3 4 5 6 7 8 9 10 11 12 13
| bool DeleteNextDNode(DNode* p) { if (p == NULL) return false; DNode* q = p->next; if (q == NULL) return false; p->next = q ->next; if (q->next != NULL) q->next->prior = p; free(q); return true; }
|
此时若要销毁这个双链表,只需找到头结点,然后循环删除后继节点即可。
1 2 3 4 5 6 7
| void DestroyList(DLinklist& L) { while (L->next != NULL) DeleteNextDNode(L); free(L); L = NULL; }
|
遍历
后向遍历
1 2 3 4
| while(p!==NULL){ p=p->next; }
|
前向遍历
1 2 3 4
| while(p!==NULL){ p=p->prior; }
|
跳过头结点的前向便利
1 2 3 4
| while(p->prior!=NULL){ p=p->prior; }
|
双链表不可以随机存取,按位查找,按值查找都只能用遍历的方式实现。时间复杂度为O(n)