c语言单链表的实现

时间:2020-04-13
本文章向大家介绍c语言单链表的实现,主要包括c语言单链表的实现使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1. slist.h

 1 #ifndef _SLIST_H
 2 #define _SLIST_H
 3 
 4 typedef struct _slist_node
 5 {
 6     struct _slist_node *p_next; /* 指向下一个结点的指针 */
 7 }slist_node_t;
 8 
 9 typedef slist_node_t slist_head_t;
10 typedef int (*slist_node_process_t)(void *p_arg, slist_node_t *p_node);
11 
12 int slist_init(slist_head_t *p_head);
13 int slist_add(slist_head_t *p_head, slist_node_t *p_pos, slist_node_t *p_node);
14 int slist_add_tail(slist_head_t *p_head, slist_node_t *p_node);
15 int slist_add_head(slist_head_t *p_head, slist_node_t *p_node);
16 int slist_del(slist_head_t *p_head, slist_node_t *p_node);
17 
18 slist_node_t *slist_prev_get(slist_head_t *p_head, slist_node_t *p_pos);
19 slist_node_t *slist_next_get(slist_head_t *p_head, slist_node_t *p_pos);
20 slist_node_t *slist_tail_get(slist_head_t *p_head);
21 slist_node_t *slist_begin_get(slist_head_t *p_head);
22 slist_node_t *slist_end_get (slist_head_t *p_head);
23 int slist_foreach(slist_head_t *p_head,
24                 slist_node_process_t pfn_node_process,
25                 void *p_arg);
26 
27 #endif

2. slist.c

 1 #include "slist.h"
 2 #include <stdlib.h>
 3 
 4 int slist_init(slist_head_t *p_head)
 5 {
 6     if (p_head == NULL)
 7     {
 8         return -1;
 9     }
10     p_head->p_next = NULL;
11     return 0;
12 }
13 
14 int slist_add(slist_head_t *p_head, slist_node_t *p_pos, slist_node_t *p_node)
15 {
16     p_node->p_next = p_pos->p_next;
17     p_pos->p_next = p_node;
18     return 0;
19 }
20 
21 int slist_add_tail(slist_head_t *p_head, slist_node_t *p_node)
22 {
23     slist_node_t *p_tmp = slist_tail_get(p_head); /* 找到尾结点 */
24     return slist_add(p_head, p_tmp, p_node); /* 添加结点至尾结点之后 */
25 }
26 
27 int slist_add_head(slist_head_t *p_head, slist_node_t *p_node)
28 {
29     return slist_add(p_head, p_head, p_node); /* 添加结点至头结点之后 */
30 }
31 
32 int slist_del(slist_head_t *p_head, slist_node_t *p_node)
33 {
34     slist_node_t *p_prev = slist_prev_get(p_head, p_node); /* 找到待删除结点的上一个结点 */
35     if (p_prev) 
36     {
37         p_prev->p_next = p_node->p_next;
38         p_node->p_next = NULL;
39         return 0;
40     }
41     return -1;
42 }
43 
44 slist_node_t *slist_prev_get(slist_head_t *p_head, slist_node_t *p_pos)
45 {
46     slist_node_t *p_tmp = p_head;
47     while ((p_tmp != NULL) && (p_tmp->p_next != p_pos))
48     {
49         p_tmp = p_tmp->p_next;
50     }
51     return p_tmp;    
52 }
53 
54 slist_node_t *slist_next_get(slist_head_t *p_head, slist_node_t *p_pos)
55 {
56     if (p_pos) 
57     {
58         return p_pos->p_next;
59     }
60     return NULL;
61 }
62 
63 slist_node_t *slist_tail_get(slist_head_t *p_head)
64 {
65     return slist_prev_get(p_head, NULL);
66 }
67 
68 slist_node_t *slist_begin_get(slist_head_t *p_head)
69 {
70     return slist_next_get(p_head, p_head);
71 }
72 
73 slist_node_t *slist_end_get (slist_head_t *p_head)
74 {
75     return NULL;
76 }
77 
78 int slist_foreach(slist_head_t *p_head,
79                   slist_node_process_t pfn_node_process,
80                   void *p_arg)
81 {
82     slist_node_t *p_tmp, *p_end;
83     int ret;
84 
85     if ((p_head == NULL) || (pfn_node_process == NULL))
86     {
87         return -1;
88     }
89     p_tmp = slist_begin_get(p_head);
90     p_end = slist_end_get(p_head);
91     while (p_tmp != p_end)
92     {
93         ret = pfn_node_process(p_arg, p_tmp);
94         if (ret < 0) 
95             return ret; /* 不再继续遍历 */
96         p_tmp = slist_next_get(p_head, p_tmp); /* 继续下一个结点 */
97     }
98     return 0;
99 }

3. demo

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <time.h>
 4 #include "slist.h"
 5 
 6 typedef struct _student
 7 {
 8     char name[10];
 9     char sex;
10     float height, weight;
11 }student_t;
12 
13 typedef struct _slist_student
14 {
15     slist_node_t node;
16     student_t student;
17 }slist_student_t;
18 
19 int student_info_read (student_t *p_student) /* 读取学生记录,随机产生,仅供测试 */
20 {
21     int i;
22 
23     for (i = 0; i < 9; i++) 
24     { /* 随机名字,由'A'~'Z'组成 */
25         p_student->name[i] = (rand() % ('z' - 'a')) + 'a';
26     }
27     p_student->name[i]= '\0';
28     p_student->sex = (rand() & 0x01) ? 'F' : 'M'; /* 随机性别 */
29     p_student->height = (float)rand() / rand();
30     p_student->weight = (float)rand() / rand();
31     return 0;
32 }
33 
34 int list_node_process (void *p_arg, slist_node_t *p_node)
35 {
36     student_t *p_s = &(((slist_student_t *)p_node)->student);
37     printf("%s : %c %.2f %.2f\n", p_s->name, p_s->sex, p_s->height, p_s->weight);
38     return 0;
39 }
40 
41 int main(int argc, char *argv[])
42 {
43     slist_head_t head;
44     slist_student_t s1, s2, s3, s4, s5;
45     srand(time(NULL));
46     slist_init(&head);
47 
48     student_info_read(&s1.student);
49     student_info_read(&s2.student);
50     student_info_read(&s3.student);
51     student_info_read(&s4.student);
52     student_info_read(&s5.student);
53 
54     slist_add_head(&head, &s1.node);
55     slist_add_head(&head, &s2.node);
56     slist_add_head(&head, &s3.node);
57     slist_add_head(&head, &s4.node);
58     slist_add_head(&head, &s5.node);
59 
60     slist_foreach(&head, list_node_process, NULL); /* 遍历链表,用户参数为NULL */
61     return 0;
62 }

原文地址:https://www.cnblogs.com/chenweilin/p/12691926.html