单向链表中的每一个节点有且只有一个指针,这个指针就是用来指向下一个节点的,单向链表顾名思义就是链表方向是单方向的,而本文要介绍的双向链表就是链表方向是双方向的,也就是双向链表中的每一个节点有两个指针,一个指针用来指向上一个节点(前驱),另一个指针用指向下一个节点(后继)。
本文主要是总结一下自己对双向链表的基本操作,当然我也只是写了几个比较简单的操作,其中包括双向链表的创建,插入节点,删除节点,还有输出节点的数据等。学习这个双向链表总的感受就是特别绕,因为涉及多个指针的操作,对于指针没有学好的人儿来说,理解双向链表还是比较困难的。
1,双向链表相当于两个单向循环链表。
2,双向链表的结点定义。
1 struct DULNode2 {3 int data;4 struct DULNode * prior;5 struct DULNode * next;6 };7 8 typedef struct DULNode * linklist;
3,单循环链表的操作都适用于双循环链表。
4,双循环链表的操作集合仍在头文件defs.h中。
5,InitList操作。双循环链表初始化操作示意图
1 #include"defs.h"2 3 void InitList(linklist *L) //改变头指针 4 { 5 *L = (linklist)malloc(sizeof(struct DULNode)); 6 if (*L == NULL) 7 exit(0); 8 (*L)->next = *L; 9 (*L)->prior = *L; 10 }
6,ClearList操作.
1 #include"defs.h"2 3 void ClearList(linklist L) 4 { 5 linklist p = L->next; //p指向链表第一个元素 6 7 while (p != L) 8 { 9 p = p->next; //p指向第二个元素10 free(p->prior);11 }12 (*L)->next = *L;13 (*L)->prior = *L;14 }
7,DestroyList操作
1 #include"defs.h"2 3 void DestroyList(linklist *L)4 {5 ClearList(*L);6 free(*L);7 *L = NULL;8 }
8,ListEmpty操作
1 #include"defs.h"2 3 int ListEmpty(linklist L)4 {5 if (L->next == L && L->prior == L) //两个条件均要有6 return 0;7 else8 return 1;9 }
9,ListLength操作
1 #include"defs.h"2 3 int ListLength(linklist L) 4 { 5 linklist p = L->next; 6 int j = 0; 7 8 while (p != L) 9 {10 ++j;11 p = p->next;12 }13 return j;14 }
10,GetElem操作
1 #include"defs.h"2 3 int GetElem(linklist L, int i, int *e) 4 { 5 linklist p = L; 6 int j = 0; 7 if (i<1 || i>ListLength(L)) 8 exit(0); 9 10 while (j11 {12 ++j;13 p = p->next;14 }15 *e = p->data;16 }
11,LocateElem操作, 没有找到返回-1
1 #include"defs.h"2 3 int LocateElem(linklist L, int e) 4 { 5 linklist p = L->next; 6 int j = 0; 7 8 while (p != L) 9 {10 ++j;11 if (p->data == e)12 return j;13 }14 return -1; 15 }
12,PriorElem操作
1 #include"defs.h"2 3 int PriorElem(linklist L, int cur_e, int *pri_e) 4 { 5 linklist p = L->next->next; //p指向第二个元素 6 7 while (p != L) 8 { 9 if (p->data == cur_e)10 {11 *pri_e = p->prior->data;12 return 0;13 }14 }15 return 0;16 }
13,NextElem操作
1 #include"defs.h"2 3 int NextElem(linklist L, int cur_e, int *nex_e) 4 { 5 linklist p = L->next->next; 6 7 while (p != L) 8 { 9 if (p->prior->data == cur_e)10 {11 *nex_e = p->data;12 return 0;13 }14 }15 return 0;16 }
14,ListInsert操作
1 #include"defs.h"2 3 int ListInsert(linklist L, int i, int e) 4 { 5 linklist p = L; //p指向头结点 6 linklist q, s; 7 int j = 0; 8 if (i<1 || i>ListLength(L)+1) 9 exit(0);10 11 while (j < i-1) //找到第i-1个结点12 {13 ++j;14 p = p->next;15 }16 q = p->next; //q指向第i个结点17 18 s = (linklist)malloc(sizeof(struct DULNode));19 s->data = e;20 21 s->next = q; //先改变向右的指针22 p->next = s; 23 s->prior = p; //改变向左的指针24 q->prior = s;25 return 0;26 }
/*学习C语言企鹅八一四九七四九一七来学习*/
15,ListDelete操作
1 #include"defs.h"2 3 int ListDelete(linklist L, int i, int *e) 4 { 5 linklist p = L; 6 linklist q; 7 int j = 0; 8 if (i<1 || i>ListLength(L)) //位置是否合理 9 exit(0);10 11 while (j < i-1) //找到第i-1个元素12 {13 ++j;14 p = p->next;15 }16 q = p->next; //p指向第i个结点17 *e = q->data;18 19 p->next = q->next;20 q->next->prior = p;21 free(q);22 return 0;23 }
16,TravelList操作
1 #include"defs.h"2 3 void TravelList(linklist L) 4 { 5 linklist p = L->next; 6 int j = 0; 7 while (p != L) 8 { 9 ++j;10 printf("第%d个元素值为:%d", j, p->data);11 p = p->next;12 }13 }
17,TravelListBack操作,逆序输出表中元素
1 #include"defs.h"2 3 void TravelListBack(linklist L) 4 { 5 linklist p = L->prior; 6 while (p != L) 7 { 8 printf("%d ", p->data); 9 p = p->prior;10 }11 printf("");12 }
举报/反馈