周立功阐释高效的双向链表如何用
在回调函数中返回负值即可终止继续遍历。一般地,若要继续遍历,则函数执行结束后返回0即可。dlist_foreach()函数的实现详见程序清单3.46。
程序清单3.46 链表遍历函数的实现
1 int dlist_foreach (dlist_head_t *p_head,
2 dlist_node_process_t pfn_node_process,
3 void *p_arg)
4 {
5 dlist_node_t *p_tmp, *p_end;
6 int ret;
7
8 if ((p_head == NULL) || (pfn_node_process == NULL)) {
9 return -1;10 }
11
12 p_tmp = dlist_begin_get(p_head);
13 p_end = dlist_end_get(p_head);
14
15 while (p_tmp != p_end) {
16 ret = pfn_node_process(p_arg, p_tmp);
17 if (ret < 0) { // 不再继续遍历
18 return ret;
19 }
20 p_tmp = dlist_next_get(p_head, p_tmp); // 继续下一个结点
21 }
22 return 0;
23 }为了便于查阅,如程序清单3.47所示展示了dlist.h文件的内容。
程序清单3.47 dlist.h文件内容
1 #ipragma once
2 #include
4
5 typedef struct _dlist_node{
6 struct _dlist_node *p_next; // 指向下一个结点的指针
7 struct _dlist_node *p_prev; // 指向下一个结点的指针
8 }dlist_node_t;
9
10 typedef dlist_node_t dlist_head_t;
11
12 // 链表遍历时的回调函数类型
13 typedef int (*dlist_node_process_t) (void *p_arg, dlist_node_t *p_node);
14
15 int dlist_init (dlist_head_t *p_head); // 链表初始化
1617 int dlist_add (dlist_head_t *p_head, dlist_node_t *p_pos, dlist_node_t *p_node); // 添加结点至指定位置
18 int dlist_add_tail(dlist_head_t *p_head, dlist_node_t *p_node); // 添加结点至链表尾部
19 int dlist_add_head (dlist_head_t *p_h
- 电源软启动的实用设计技巧(07-16)
- 周立功:动态分布内存——malloc()函数与calloc()函数(07-22)
- 周立功“程序设计与数据结构”:深度解剖动态分布内存的free()函数与realloc()函数(07-25)
- 周立功教你学程序设计技术:做好软件模块的分层设计,回调函数要这样写(07-30)
- 周立功教你学C语言编程:教你数组是如何保存指针的(07-31)
- 算法的泛化问题,这些坑你可能都经历过!|周立功教你学软件设计(08-01)
