单链表操作

 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 **********************************************/

 

 

posted @ 2013-07-05 13:47  尘虑萦心  阅读(199)  评论(0编辑  收藏  举报