C语言版本:单链表的实现

slist.h

 1 #ifndef __SLIST_H__
 2 #define __SLIST_H__
 3 
 4 #include<cstdio>
 5 #include<malloc.h>
 6 #include<assert.h>
 7 typedef int ElemType;
 8 typedef struct Node { //定义单链表中的结点信息
 9     ElemType data; //结点的数据域
10     struct Node *next; //结点的指针域
11 }Node,*PNode;
12 typedef struct List { //定义单链表的链表信息
13     PNode first; //first指向单链表中的第一个结点
14     PNode last; //last指向单链表中的最后一个结点
15     size_t size; //记录单链表中的结点个数
16 }List;
17 
18 void InitList(List *list);//初始化单链表
19 void push_back(List *list, ElemType x);//在单链表的末尾插入元素
20 void push_front(List *list, ElemType x);//在单链表的头部插入元素
21 void show_list(List *list);//打印单链表
22 void pop_back(List *list);//删除单链表的最后一个元素
23 void pop_front(List *list);//删除单链表的第一个元素
24 void insert_val(List *list, ElemType val);//将数据元素插入到单链表中(要求此时单链表中的数据元素顺序排列)
25 Node* find(List *list, ElemType x);//查找单链表中数据值为x的结点
26 int length(List *list);//求单链表的长度
27 void delete_val(List *list, ElemType x);//按值删除单链表中的某个数据元素
28 void sort(List *list);//对单链表进行排序
29 void reverse(List *list);//逆置单链表
30 void clear(List *list);//清除单链表
31 void destroy(List *list);//摧毁单链表
32 
33 #endif //__SLIST_H__

slist.cpp

  1 #include"slist.h"
  2 
  3 void InitList(List *list) {
  4     list->first = list->last = (Node*)malloc(sizeof(Node)); //头结点
  5     assert(list->first != NULL);
  6     list->first->next = NULL;
  7     list->size = 0;
  8 }
  9 
 10 void push_back(List *list, ElemType x) {
 11     //step 1:创建一个新的结点
 12     Node *s = (Node*)malloc(sizeof(Node));
 13     assert(s != NULL);
 14     s->data = x;
 15     s->next = NULL;
 16     //step 2:将新结点插入单链表的表尾
 17     list->last->next = s;
 18     list->last = s;
 19     //step 3:更新单链表的长度
 20     list->size++;
 21 }
 22 
 23 void push_front(List *list, ElemType x) {
 24     //step 1:创建一个新的结点
 25     Node *s = (Node*)malloc(sizeof(Node));
 26     assert(s != NULL);
 27     s->data = x;
 28     s->next = NULL;
 29     //step 2:将新结点插入单链表的表头
 30     s->next = list->first->next;
 31     list->first->next = s;
 32     //step 3:判断插入的结点是否是单链表的第一个结点,若是更新链表的尾指针
 33     if (list->size == 0)
 34         list->last = s;
 35     //step 4:更新单链表的长度
 36     list->size++;
 37 }
 38 
 39 void show_list(List *list) {
 40     //step 1:指针p指向单链表的第一个结点
 41     Node *p = list->first->next;
 42     //step 2:循环打印结点的信息
 43     while (p != NULL) {
 44         printf("%d->", p->data);
 45         p = p->next;
 46     }
 47     printf("Nul.
");
 48 
 49 }
 50 
 51 void pop_back(List *list) {
 52     //step 1:判断单链表是否为空
 53     if (list->size == 0) return;
 54     //step 2:定义指针p使其指向目标结点的前一个结点
 55     Node *p = list->first;//从头结点开始
 56     while (p->next != list->last)
 57         p = p->next;
 58     //step 3:删除目标结点
 59     free(list->last);
 60     list->last = p;
 61     list->last->next = NULL;
 62     //step 4:更新单链表的长度
 63     list->size--;
 64 }
 65 
 66 void pop_front(List *list) {
 67     //step 1:判断单链表是否为空
 68     if (list->size == 0) return;
 69     //step 2:定义指针p使其指向目标结点的前一个结点
 70     Node *p = list->first->next;
 71     //step 3:删除目标结点
 72     list->first->next = p->next;
 73     free(p);
 74     //step 4:判断删除的结点是否是单链表的最后一个结点,若是则更新单链表的尾指针
 75     if (list->size == 1)
 76         list->last = list->first;
 77     //step 4:更新单链表的长度
 78     list->size--;
 79 }
 80 
 81 void insert_val(List *list, ElemType x) {
 82     //step 1:创建一个新的结点
 83     Node *s = (Node*)malloc(sizeof(Node));
 84     assert(s != NULL);
 85     s->data = x;
 86     s->next = NULL;
 87     //step 2:定义指针p使其指向待插入位置的前一个结点
 88     Node *p = list->first;//从头结点开始
 89     while (p->next != NULL && p->next->data < s->data)
 90         p = p->next;
 91     //step 3:判断结点的待插入位置是否是表尾,若是则更新单链表的尾指针
 92     if (p->next == NULL)
 93         list->last = s;
 94     //step 4:插入结点
 95     s->next = p->next;
 96     p->next = s;
 97     //step 5:更新单链表长度
 98     list->size++;
 99 }
100 
101 Node* find(List *list, ElemType x) {
102     //step 1:指针p指向单链表的第一个结点
103     Node *p = list->first->next;
104     //step 2:按照循环顺序查找链表结点
105     while (p != NULL && p->data != x)
106         p = p->next;
107     return p;
108 }
109 
110 int length(List *list) {
111     return list->size;
112 }
113 
114 void delete_val(List *list, ElemType x) {
115     //step 1:判断单链表是否为空
116     if (list->size == 0) return;
117     //step 2:确定结点在单链表中的位置,并判断其是否存在于单链表中
118     Node *p = find(list, x);
119     if (p == NULL) {
120         printf("要删除的数据不存在!
");
121         return;
122     }
123     //step 3:判断结点位置是否是表尾
124     if (p == list->last)//是表尾
125         pop_back(list);
126     else {//不是表尾
127         Node *q = p->next;
128         p->data = q->data;
129         p->next = q->next;
130         free(q);
131         list->size--;
132     }
133 }
134 
135 void sort(List *list) {
136     //step 1:判断单链表中的结点数是否为0或1
137     if (list->size == 0 || list->size == 1) return;
138     //step 2:将单链表中第一个结点之后的链表部分截出,方便重新按顺序插入链表之中
139     Node *s = list->first->next; // 指针s指向单链表的第一个节点
140     Node *p = s->next;//q指向s后面的结点
141     list->last = s;//单链表的尾指针指向单链表的第一个结点
142     list->last->next = NULL;//截断链表
143     //step 3:将截出的链表中的结点根据其数据域大小重新插入到原来链表中
144     while (p != NULL) {
145         s = p;
146         p = p->next;
147         Node *q = list->first;
148         while (q->next != NULL && q->next->data < s->data)
149             q = q->next;
150         if (q->next == NULL)//判断q此时指向的是否是单链表的最后一个结点,若是则更新链表的尾指针
151             list->last = s;
152         //将结点重新插入链表
153         s->next = q->next;
154         q->next = s;
155     }
156 }
157 
158 void reverse(List *list) {
159     //step 1:判断单链表中的结点数是否为0或1
160     if (list->size == 0 || list->size == 1) return;
161     //step 2:将单链表中第一个结点之后的链表部分截出,然后将截出的链表中的结点按头插法重新插入到原链表中
162     Node *p = list->first->next;
163     Node *q = p->next;
164     list->last = p;
165     list->last->next = NULL;
166 
167     while (q != NULL) {
168         p = q;
169         q = q->next;
170         p->next = list->first->next;
171         list->first->next = p;
172     }
173 }
174 
175 void clear(List *list) {
176     //step 1:判断单链表是否为空
177     if (list->size == 0) return;
178     //step 2:释放单链表中的每一个结点
179     Node *p = list->first->next;
180     while (p != NULL) {
181         list->first->next = p->next;
182         free(p);
183         p = list->first->next;
184     }
185     //step 3:头指针和尾指针重新都指向头结点
186     list->last = list->first;
187     //step 4:更新链表长度
188     list->size = 0;
189 }
190 
191 void destroy(List *list) {
192     //step 1:清空单链表
193     clear(list);
194     //step 2:释放头结点
195     free(list->first);
196     //step 3:头指针和尾指针都赋值为空
197     list->first = list->last = NULL;
198 }

main.cpp

 1 #include"slist.h"
 2 
 3 void main() {
 4     List mylist;
 5     InitList(&mylist);
 6 
 7     ElemType item;
 8     Node *p = NULL;
 9     int select = 1;
10     while (select) {
11         printf("*******************************************
");
12         printf("*[1]  push_back        [2]  push_front    *
");
13         printf("*[3]  show_list        [4]  pop_back      *
");
14         printf("*[5]  pop_front        [6]  insert_val    *
");
15         printf("*[7]  find             [8]  length        *
");
16         printf("*[9]  delete_val       [10] sort          *
");
17         printf("*[11] reverse          [12] clear         *
");
18         printf("*[13*] destroy         [0] quit_system    *
");
19         printf("*******************************************
");
20         printf("请选择:>>");
21         scanf("%d", &select);
22         if (select == 0) break;
23         switch (select) {
24         case 1:
25             printf("请输入要插入的数据(-1结束):>");
26             while (scanf("%d", &item), item != -1) {
27                 push_back(&mylist, item);
28             }
29             break;
30         case 2:
31             printf("请输入要插入的数据(-1结束):>");
32             while (scanf("%d", &item), item != -1) {
33                 push_front(&mylist, item);
34             }
35             break;
36         case 3:
37             show_list(&mylist);
38             break;
39         case 4:
40             pop_back(&mylist);
41             break;
42         case 5:
43             pop_front(&mylist);
44             break;
45         case 6:
46             printf("请输入要插入的数据:>");
47             scanf("%d", &item);
48             insert_val(&mylist, item);
49             break;
50         case 7:
51             printf("请输入要查找的数据:>");
52             scanf("%d", &item);
53             p = find(&mylist, item);
54             if (p == NULL)
55                 printf("要查找的数据在单链表中不存在!
");
56             break;
57         case 8:
58             printf("单链表的长度为%d
", length(&mylist));
59             break;
60         case 9:
61             printf("请输入要删除的值:>");
62             scanf("%d", &item);
63             delete_val(&mylist, item);
64             break;
65         case 10:
66             sort(&mylist);
67             break;
68         case 11:
69             reverse(&mylist);
70             break;
71         case 12:
72             clear(&mylist);
73             break;
74             //case 13:
75             //destroy(&mylist);
76             //break;
77         default:
78             printf("选择错误,请重新选择!
");
79             break;
80         }
81     }
82     destroy(&mylist); //程序结束,摧毁链表
83 }
原文地址:https://www.cnblogs.com/duwenxing/p/7569376.html