数据结构(3) - 双向链表
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
代码如下:
double-list.c
1 /** 2 * C data structure double linked list example. 3 * 4 * License - MIT. 5 */ 6 7 #include "double-list.h" 8 9 10 /** 11 * doulist_empty - Determine if the list is empty. 12 */ 13 bool doulist_empty(LPDOUBLELIST lpHead) 14 { 15 return (lpHead == lpHead->next); 16 } 17 18 19 /** 20 * doulist_show - Display list data. 21 */ 22 int doulist_show(LPDOUBLELIST lpHead) 23 { 24 LPDOUBLELIST tmp; 25 26 for (tmp = lpHead->next; tmp != lpHead; tmp = tmp->next) 27 printf("%d ", tmp->data); 28 29 printf("\n"); 30 31 return 0; 32 } 33 34 35 /** 36 * doulist_insert - Add the specified data at specified node next location. 37 */ 38 int doulist_insert(LPDOUBLELIST lpHead, LPDOUBLELIST lpNode) 39 { 40 lpNode->next = lpHead->next; 41 lpHead->next->prev = lpNode; 42 lpNode->prev = lpHead; 43 lpHead->next = lpNode; 44 45 return 0; 46 } 47 48 49 /** 50 * doulist_insert_tail - Insert data to list tail. 51 */ 52 int doulist_insert_tail(LPDOUBLELIST lpHead, LPDOUBLELIST lpNode) 53 { 54 lpNode->prev = lpHead->prev; 55 lpHead->prev->next = lpNode; 56 lpNode->next = lpHead; 57 lpHead->prev = lpNode; 58 59 return 0; 60 } 61 62 63 /** 64 * doulist_del - Deletes the specified data by specified node next location. 65 */ 66 int doulist_del(LPDOUBLELIST lpNode) 67 { 68 lpNode->prev->next = lpNode->next; 69 lpNode->next->prev = lpNode->prev; 70 71 return 0; 72 } 73 74 75 /** 76 * doulist_init - Initialize double linked list. 77 */ 78 int doulist_init(LPDOUBLELIST *lpHead) 79 { 80 *lpHead = (LPDOUBLELIST) malloc(sizeof(DOUBLELIST)); 81 if (NULL == *lpHead) { 82 return -1; 83 } 84 85 (*lpHead)->next = *lpHead; 86 (*lpHead)->prev = *lpHead; 87 88 return 0; 89 } 90 91 92 /** 93 * doulist_clear - clear double linked list. 94 */ 95 int doulist_clear(LPDOUBLELIST lpHead) 96 { 97 LPDOUBLELIST tmp; 98 99 if (!doulist_empty(lpHead)) { 100 for (tmp = lpHead->next; tmp != lpHead; tmp = tmp->next) { 101 doulist_del(tmp); 102 free(tmp); 103 } 104 } 105 106 tmp = NULL; 107 108 free(lpHead); 109 lpHead = NULL; 110 111 return 0; 112 }
double-list.h
1 /** 2 * C data structure double linked list example. 3 * 4 * License - MIT. 5 */ 6 7 #ifndef __DOUBLE_LIST_H__ 8 #define __DOUBLE_LIST_H__ 9 10 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <stdbool.h> 14 15 typedef struct _DOUBLELIST{ 16 int data; 17 struct _DOUBLELIST *prev, *next; 18 } DOUBLELIST, *LPDOUBLELIST; 19 20 21 bool doulist_empty (LPDOUBLELIST lpHead); 22 int doulist_show (LPDOUBLELIST lpHead); 23 int doulist_insert (LPDOUBLELIST lpHead, LPDOUBLELIST lpNode); 24 int doulist_insert_tail (LPDOUBLELIST lpHead, LPDOUBLELIST lpNode); 25 int doulist_del (LPDOUBLELIST lpNode); 26 int doulist_init (LPDOUBLELIST *lpHead); 27 int doulist_clear (LPDOUBLELIST lpHead); 28 29 30 #endif /* __DOUBLE_LIST_H__ */
main.c
1 /** 2 * C data structure double linked list example. 3 * 4 * License - MIT. 5 */ 6 7 #include <stdio.h> 8 9 #include "double-list.h" 10 11 12 #define MAX_TEST_NUM 10 13 14 15 /** 16 * test_sort - Sort the data. 17 */ 18 int test_sort(LPDOUBLELIST lpHead) 19 { 20 LPDOUBLELIST pos, tmp; 21 22 pos = lpHead->prev; 23 24 while (pos != lpHead) 25 { 26 if (1 == (pos->data % 2)) { 27 pos = pos->prev; 28 } 29 else { 30 tmp = pos; 31 pos = pos->prev; 32 33 doulist_del(tmp); 34 doulist_insert_tail(lpHead, tmp); 35 } 36 } 37 38 return 0; 39 } 40 41 42 /** 43 * test_create - Create single list example. 44 */ 45 int test_create(LPDOUBLELIST lpHead) 46 { 47 int i; 48 LPDOUBLELIST newNode; 49 50 for (i = 0; i < MAX_TEST_NUM; i++) { 51 newNode = (LPDOUBLELIST) malloc(sizeof(DOUBLELIST)); 52 if (NULL == newNode) { 53 return -1; 54 } 55 56 newNode->data = i + 1; 57 doulist_insert_tail(lpHead, newNode); 58 } 59 60 return 0; 61 } 62 63 64 /** 65 * Main function. 66 */ 67 int main(void) 68 { 69 LPDOUBLELIST lphead = NULL; 70 71 doulist_init(&lphead); 72 73 test_create(lphead); 74 doulist_show(lphead); 75 76 test_sort(lphead); 77 doulist_show(lphead); 78 79 doulist_clear(lphead); 80 81 return 0; 82 }
Makefile
1 # Makefile 2 CC = gcc 3 CFLAGS = -Wall -g -O0 4 5 SRC = main.c double-list.c 6 7 OBJ = doulist-test 8 9 $(OBJ) : $(SRC) 10 $(CC) $(CFLAGS) -o $@ $^ 11 12 clean: 13 $(RM) $(OBJ) *.o *.*.sw?
完整代码请参考Github: [Link] [https://github.com/Phoebus-Ma/C-Helper/tree/main/Class-1/List.C]