1 #ifndef LIST_H
2 #define LIST_H
3
4 typedef unsigned int Item;
5 typedef unsigned char byte;
6 struct node
7 {
8 Item item; // 卫星数据
9 struct node * next;
10 };
11 typedef struct node * List;
12
13 void ListAddItem(List *plist, const Item item);
14 struct node * ListSearchItem(const List list, const Item item);
15 void ListDelItem(List *plist, const Item item);
16 void ListDel(List *plist);
17 void ListInvert(List *plist);
18 bool ListIsLoop(const List list);
19 struct node * ListConcatenate(List list1, List list2);
20 #endif
1 #include "stdafx.h"
2 #include "list.h"
3 #include <assert.h>
4 #include <malloc.h>
5
6 static inline void CopyItem(Item item, struct node* pnode)
7 {
8 pnode->item = item;
9 }
10
11 static inline int ItemCmp(Item item1, Item item2)
12 {
13 return item1 > item2 ? 1 : (item1 == item2 ? 0 : -1);
14 }
15
16
17 /**********************************************
18 向链表中插入节点
19 当链表为空时,需要改变链表头所指向的内容,因此入参用链表头指针
20 **********************************************/
21 void ListAddItem(List *plist, const Item item)
22 {
23 assert(NULL != plist);
24
25 struct node *pnew;
26 pnew = (struct node *)malloc(sizeof(struct node));
27 assert(NULL != pnew);
28
29 CopyItem(item,pnew);
30
31 // 从小到大排列
32 struct node *pscan = *plist;
33 struct node *pinsert = NULL;
34 while (NULL != pscan)
35 {
36 // 若是只需要插入到链表尾,可以去掉if-else条件,将循环体改为
37 // pinsert = pscan; pscan = pscan->next;
38 if (ItemCmp(pscan->item, item) < 0)
39 {
40 pinsert = pscan;
41 pscan = pscan->next;
42 }
43 else
44 {
45 break;
46 }
47 }
48
49 // 无比item小的节点或是空链表,链表头插入
50 if (NULL == pinsert)
51 {
52 pnew->next = pscan;
53 *plist = pnew;
54 }
55 else // 链表中间或者链表尾部
56 {
57 pnew->next = pscan;
58 pinsert->next = pnew;
59 }
60 }
61
62 /**********************************************
63 若相应的item存在,则返回第一个item的前驱(头节点的
64 前驱为NULL)
65 否则返回NULL
66 **********************************************/
67 struct node * ListSearchItem(const List list, const Item item)
68 {
69 struct node * pscan = list;
70 struct node * pprev = NULL;
71
72 while (NULL != pscan)
73 {
74 if (ItemCmp(pscan->item, item) == 0)
75 {
76 return pprev;
77 }
78 else
79 {
80 pprev = pscan;
81 pscan = pscan->next;
82 }
83 }
84
85 return NULL;
86 }
87
88
89 /**********************************************
90 // 删除元素
91 // 返回值:0,删除失败(不存在该item),1:删除成功
92 **********************************************/
93 void ListDelItem(List *plist, const Item item)
94 {
95 assert(NULL != plist);
96
97 struct node *ptemp = *plist;
98 if (NULL == ptemp) // 空链表
99 return;
100
101 struct node *pdel = ListSearchItem(*plist, item);
102 if (NULL == pdel)
103 {
104 if (ItemCmp((*plist)->item, item) == 0)
105 {
106 pdel = *plist;
107 *plist = pdel->next;
108 free(pdel);
109 }
110 }
111 else
112 {
113 ptemp = pdel->next; // item所在节点
114 pdel->next = pdel->next->next;
115 free(ptemp);
116 }
117 }
118
119
120 /**********************************************
121 // 删除链表
122 **********************************************/
123 void ListDel(List *plist)
124 {
125 assert(NULL != plist);
126
127 struct node *pscan;
128 struct node *pdel;
129
130 pscan = *plist;
131
132 while (NULL != pscan)
133 {
134 pdel = pscan;
135 pscan = pscan->next;
136 free(pdel);
137 }
138
139 *plist = NULL;
140 }
141
142 /**********************************************
143 单链表翻转:采用3个指针就地翻转
144 **********************************************/
145 void ListInvert(List *plist)
146 {
147 assert(NULL != plist);
148
149 struct node *head, *tail, *pscan;
150
151 head = NULL;
152 pscan = *plist;
153
154 while (pscan)
155 {
156 tail = head;
157 head = pscan;
158 pscan = pscan->next;
159 head->next = tail;
160 }
161
162 *plist = head;
163 }
164
165 /**********************************************
166 检查单链表是否有环:
167 采用2个指针以不同的步长移动,若有环,则快的一定
168 能追上慢的
169 **********************************************/
170 bool ListIsLoop(const List list)
171 {
172 struct node *fast;
173 struct node *slow;
174
175 if (NULL == list)
176 return false;
177
178 slow = list;
179 fast = list->next;
180
181 while (NULL != fast)
182 {
183 if (slow == fast)
184 return true;
185
186 slow = slow->next;
187
188 fast = fast->next;
189 if (NULL == fast)
190 return false;
191 fast = fast->next;
192 }
193
194 return false;
195 }
196
197 /**********************************************
198 串接2个单链表:
199 将list2串接到list1之后,返回串接后的链表头
200 **********************************************/
201 struct node * ListConcatenate(List list1, List list2)
202 {
203 struct node *ptemp;
204
205 if (NULL == list1)
206 return list2;
207
208 ptemp = list1;
209 while (NULL != ptemp->next)
210 ptemp = ptemp->next;
211
212 ptemp->next = list2;
213
214 return list1;
215 }
216
217 /**********************************************
218 判断两个链表是否相交:
219 将两个链表串接起来,判断是否有环
220 **********************************************/