简单链表操作

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 struct Demo
  4 {
  5     int num;
  6     struct Demo * nextList;
  7 };
  8 typedef struct Demo LIT;
  9 LIT* creatList(void);
 10 LIT * creatsortList(void);
 11 void destory1List(LIT* firstHead);
 12 void destoryList(LIT* firstHead);
 13 void printList1(LIT* firstHead);
 14 void printList2(LIT* firstHead);
 15 void reversePrintList(LIT* firstHead);
 16 LIT* findList(LIT* firstHead, int value);
 17 LIT * deleteList(LIT* firstHead, int value);
 18 LIT * insertList(LIT * firstHead, int num);
 19 LIT* findMax(LIT * firstHead);
 20 LIT* reverseList(LIT * firstHead);//链表的逆序组织
 21 LIT* reverList(LIT*firstHead, int s1, int t1, int s2, int t2);
 22 int supList(LIT* firstA, LIT* firstB);//判断B是否是A的连续子序列 
 23 LIT* findList2(LIT*firstHead, int index);//index为序号,以1开始
 24 
 25 LIT* mergeSortList(LIT *first1, LIT *first2);
 26 void findSite(LIT*headPtr, int value, LIT**prevoiusPtr, LIT**currentPtr);
 27 int main()
 28 {
 29     printf("please input nums:");
 30     /*LIT * first = NULL;
 31     first = creatList();//创造一个乱序的链表
 32     printList(first);//打印
 33     LIT* found =NULL;
 34     found = findList(first, 34);//在链表中找到34,并返回34对应的LIT地址
 35     first = deleteList(first, 45);//删除45
 36     printList(first);
 37     first = insertList(first ,35);//插入35
 38     */
 39     LIT* first1 = creatsortList();//创建一个有序链表
 40     printList2(first1);
 41     LIT* first2 = creatsortList();//创建一个有序链表
 42     printList2(first2);
 43     mergeSortList(first1, first2);
 44     printList2(first1);
 45     /*LIT* maxPtr = findMax(first);
 46     printf("\n%d", maxPtr->num);*/
 47 
 48     destoryList(first1);
 49     first1 = NULL;
 50     
 51     system("PAUSE");
 52     return 0;
 53 }
 54 LIT* creatList(void)
 55 {
 56     int numd, n = 0;
 57     scanf("%d", &numd);
 58     LIT* fisrtHead = NULL;
 59     LIT* p1 = NULL;
 60     LIT* p2 = NULL;
 61     p1 = (LIT*)(malloc(sizeof(LIT)));
 62     p2 = (LIT*)(malloc(sizeof(LIT)));
 63     while (numd != -1)//读取数字,以-1结束,不将-1加入链表 
 64     {
 65         p1->num = numd;
 66         n++;//记录链表节点数 
 67         if (n == 1)//判断是否是头节点 
 68             fisrtHead = p1;//头节点赋给firstHead 
 69         else
 70             p2->nextList = p1;//将新节点与链表相连 
 71         p2 = p1;
 72         p1 = (LIT*)(malloc(sizeof(LIT)));//创建下一个节点 
 73         scanf("%d", &numd);
 74     }
 75     p2->nextList = NULL;//最末节点的nextList为NULL 
 76     return fisrtHead;
 77 }
 78 
 79 void destoryList1(LIT* firstHead)//逐个free链表的节点 
 80 {
 81     LIT * temper = NULL;
 82     while (firstHead != NULL)
 83     {
 84         temper = firstHead;
 85         firstHead = firstHead->nextList;
 86         free(temper);
 87     }
 88 }
 89 void printList1(LIT* firstHead)//顺序
 90 {
 91     if (firstHead == NULL)
 92     {
 93         printf("list null");
 94         return;
 95     }
 96     printf("Now print:");
 97     LIT *p1 = NULL;
 98     p1 = firstHead;
 99     while (p1 != NULL)
100     {
101         printf("%d  ", p1->num);
102         p1 = p1->nextList;
103     }
104     printf(" NULL!\n");
105 }
106 void printList2(LIT* firstHead)
107 {
108     if (firstHead != NULL)
109     {
110         printf("%d ", firstHead->num);
111         printList2(firstHead->nextList);
112     }
113     else
114         printf("NULL!\n");
115 }
116 void reversePrintList(LIT* firstHead)//强调的是逆序,倒着,不是大小
117 {
118     if (firstHead != NULL)
119     {
120         reversePrintList(firstHead->nextList);
121         printf("%d ", firstHead->num);
122     }
123 }
124 void destoryList(LIT* firstHead)
125 {
126     if (firstHead == NULL)
127     {
128         printf("list null!\n");
129         return;
130     }
131     /*LIT *p1=NULL,*p2=NULL;
132     p1 = firstHead->nextList;
133     free(firstHead);
134     while (p1 != NULL)
135     {
136         p2 = p1->nextList;
137         free(p1);
138         p1 = p2;
139     }*/
140     LIT * temper = NULL;
141     while (firstHead != NULL)
142     {
143         temper = firstHead;
144         firstHead = firstHead->nextList;
145         free(temper);
146     }
147 }
148 LIT* findList(LIT* firstHead, int value)
149 {
150     if (firstHead == NULL)
151     {
152         printf("list null!\n");
153         return firstHead;
154     }
155     LIT *p1 = firstHead;
156     while (p1 != NULL && (p1->num) != value)
157     {
158         p1 = p1->nextList;
159     }
160     if (p1 != NULL)
161         printf("\n%d be found!\n", p1->num);
162     else
163         printf("no find!\n");
164     return p1;
165 }
166 LIT * deleteList(LIT* firstHead, int value)
167 {
168     if (firstHead == NULL)
169     {
170         printf("list null");
171         return firstHead;
172     }
173     LIT*p1 = NULL, *p2 = NULL;
174     p1 = firstHead;
175     while (p1->nextList != NULL && (p1->num) != value)
176     {
177         p2 = p1;
178         p1 = p1->nextList;
179     }
180     if (p1->num == value)
181     {
182         if (p1 == firstHead)
183             firstHead = p1->nextList;//first
184         else
185             p2->nextList = p1->nextList;//mid+last(p1->next==NULL)
186         printf("delete:%d\n", value);
187     }
188     else
189         printf(" no find!\n");
190     return firstHead;
191 }
192 LIT * insertList(LIT * firstHead, int num)//(从小到大)顺序排列的插入
193 {
194     LIT *stud = (LIT*)malloc(sizeof(LIT));
195     if (num == -1)//-1结束 
196         return firstHead;
197     if (stud != NULL) //创建节点成功 ,则赋值 
198     {
199         stud->num = num;
200         stud->nextList = NULL;
201     }
202     LIT *p1 = NULL;
203     LIT *p2 = NULL;
204     p1 = firstHead;//p1与firstHead 指向相同 ,用于不断nextList 找出需要的节点 
205     if (firstHead == NULL)//头节点为NULL ,则stud作为新的头节点 
206     {
207         firstHead = stud;
208         stud->nextList = NULL;
209     }
210     else
211     {
212         while ((stud->num > p1->num) && (p1->nextList != NULL))// 循环 找出可插入的节点位置 
213         {
214             p2 = p1;//p2为在循环时p1的上一节点 
215             p1 = p1->nextList;
216         }
217         if (stud->num <= p1->num)
218         {
219             if (firstHead == p1)//first插入 
220                 firstHead = stud;
221             else
222                 p2->nextList = stud;//mid插入 
223             stud->nextList = p1;
224         }
225         else //last插入 ,作为末节点 
226         {
227             p1->nextList = stud;
228             stud->nextList = NULL;
229         }
230     }
231     return firstHead;
232 }
233 LIT* creatsortList(void)//创建一个顺序的链表(从小到大) 
234 {
235     int num;
236     LIT * firstHead = NULL;
237     scanf("%d", &num);//读入num 
238     while (num != -1)
239     {
240         firstHead = insertList(firstHead, num);//将num插入原链表里,并返回新的头节点 
241         scanf("%d", &num);//循环读入num 
242     }
243     return firstHead;//返回头节点 
244 }
245 LIT* findMax(LIT * firstHead)//找到最大值所在节点
246 {
247     LIT * maxPtr = NULL;
248     if (firstHead->nextList == NULL)//最后一个节点返回firstHead 
249         return firstHead;
250     else
251     {
252         maxPtr = findMax(firstHead->nextList);//递归找出下一节点后的max 对应的节点 
253         return maxPtr->num > firstHead->num ? maxPtr : firstHead;//比较当前节点的num与 macPtr指向的num,返回较大值的节点位置 
254     }
255 }
256 
257 LIT* findMin(LIT * firstHead)//找到最小值所在节点 
258 {
259     LIT * minPtr = NULL;
260     if (firstHead->nextList == NULL)//最后一个节点返回firstHead 
261         return firstHead;
262     else
263     {
264         minPtr = findMin(firstHead->nextList); //递归找出下一节点后的min 对应的节点 
265         return minPtr->num < firstHead->num ? minPtr : firstHead;//比较当前节点的num与 macPtr指向的num,返回较小值的节点位置
266     }
267 }
268 
269 int totalList(LIT* firstHead)//求和 (num) 
270 {
271     int sum = 0;
272     while (firstHead != NULL)
273     {
274         sum += firstHead->num;
275         firstHead = firstHead->nextList;
276     }
277     return sum;
278 }
279 LIT* reverseList(LIT * firstHead)//链表的逆序组织
280 {
281     LIT* newHeader = NULL, *currentPtr = NULL;
282     while (firstHead != NULL)
283     {
284         currentPtr = firstHead;
285         firstHead = firstHead->nextList;
286         if (newHeader == NULL)
287         {
288             newHeader = currentPtr;
289             currentPtr->nextList = NULL;
290         }
291         else
292         {
293             currentPtr->nextList = newHeader;
294             newHeader = currentPtr;
295         }
296     }
297     return newHeader;
298 }
299 int supList(LIT* firstA, LIT* firstB)//判断B是否是A的连续子序列 
300 {
301     LIT* p1 = firstB, *p2 = firstA;
302     //记录最初的firstB,firstA
303     while (firstA != NULL)//判断A是否能够容纳B(比B长) 
304     {
305 
306         while ((firstA != NULL) && (firstB != NULL) && (firstA->num == firstB->num))//比对是否连续相等
307         {
308             firstA = firstA->nextList;
309             firstB = firstB->nextList;
310         }
311         if (firstB == NULL)//B能成功遍历完
312             return 1;
313         else
314         {
315             firstB = p1;
316             firstA = p2->nextList;
317             p2 = firstA;
318         }//重新从B的首节点开始
319     }
320     return 0;
321 }
322 int lengthList(LIT*firstHead)//链表长度 
323 {
324     int n = 0;
325     while (firstHead != NULL)
326     {
327         n++;
328         firstHead = firstHead->nextList;
329     }
330     return n;
331 }
332 
333 
334 //实现交换此链表中任意指定的两段,第一段为[s1,t1],第二段[s2,t2]。s1、t1、s2、t2代表链表的第几个节点,且满足s1<=t1,s2<=t2,t1<s2,s2一定小于等于链表节点的总个数
335 LIT* reverList(LIT*firstHead, int s1, int t1, int s2, int t2)
336 {
337     LIT* s1ptr = findList(firstHead, s1);
338     LIT* t1ptr = findList(firstHead, t1);
339     LIT* s2ptr = findList(firstHead, s2);
340     LIT* t2ptr = findList(firstHead, t2);
341     LIT* s1suptr = findList(firstHead, s1 - 1);
342     LIT* t1laptr = findList(firstHead, t1 + 1);
343     LIT* s2suptr = findList(firstHead, s2 - 1);
344 
345     int len = lengthList(firstHead);
346     if (s1 != 1 && t2 != len)
347     {
348         LIT* s1suptr = findList(firstHead, s1 - 1);
349         LIT* t2laptr = findList(firstHead, t2 + 1);
350         s1suptr->nextList = s2ptr;
351         //s1前一个与s2相连 
352         t1ptr->nextList = t2laptr;
353         //t2后一个与t1相连 
354     }
355     else if (s1 == 1 && t2 != len)
356     {
357         LIT* t2laptr = findList(firstHead, t2 + 1);
358         t1ptr->nextList = t2laptr;
359         //t2后一个与t1相连 
360         firstHead = s2ptr;//以s2为头节点 
361     }
362     else if (s1 != 1 && t2 == len)
363     {
364         LIT* s1suptr = findList(firstHead, s1 - 1);
365         s1suptr->nextList = s2ptr;
366         //s1前一个与s2相连 
367         t1ptr->nextList = NULL;//以t1为尾节点 
368     }
369     else
370     {
371         t1ptr->nextList = NULL;//以t1为尾节点 
372         firstHead = s2ptr;//以s2为头节点    
373     }
374     if ((t1 + 1) != s2)
375     {
376         t2ptr->nextList = t1laptr;
377         //t1后一个与t2相连 
378         s2suptr->nextList = s1ptr;
379         //s2前一个与s1相连 
380     }
381     else
382     {
383         t2ptr->nextList = s1ptr;//t2与s1相连 
384     }
385     return firstHead;
386 }
387 LIT* findList2(LIT*firstHead, int index)
388 {
389     int n = 1;
390     while (firstHead != NULL && n < index)
391     {
392         n++;
393         firstHead = firstHead->nextList;
394     }
395     return firstHead;
396 }
397 LIT* mergeSortList(LIT *first1, LIT *first2)
398 {
399     LIT* left2Ptr, *previous1Ptr, *previous2Ptr, *current1Ptr, *current2Ptr;
400     while (first2 != NULL)
401     {
402         left2Ptr = first2;
403         previous1Ptr = NULL;
404         previous2Ptr = NULL;
405         current1Ptr = NULL;
406         current2Ptr = NULL;
407         findSite(first1, left2Ptr->num, &previous1Ptr, &current1Ptr);
408         //从1中找到left2Ptr指向的首数字能插入的地方
409         if (current1Ptr == NULL)//1都小于2,插入尾部
410         {
411             previous1Ptr->nextList = left2Ptr;
412             first2 = NULL;
413         }
414         else
415         {
416             findSite(first2, current1Ptr->num, &previous2Ptr, &current2Ptr);
417             //比较并确定链表2本次可归并的连续K个结点;这段结点由left2Ptr和previous2Ptr指向 
418             if (current1Ptr == first1)//插入首部
419             {
420                 (previous2Ptr)->nextList = first1;
421                 first1 = left2Ptr;
422             }
423             else//插中间
424             {
425                 previous1Ptr->nextList = left2Ptr;
426                 previous2Ptr->nextList = current1Ptr;
427             }
428             first2 = current2Ptr;
429         }
430     }
431     return first1;
432 }
433 
434 void findSite(LIT*headPtr, int value, LIT**prevoiusPtr, LIT**currentPtr)//查找插入的位置,改变prePtr,currPtr,使value处在指向中间
435 {
436     *prevoiusPtr = NULL;
437     *currentPtr = headPtr;
438     while ((*currentPtr != NULL) && (*currentPtr)->num < value)
439     {
440         *prevoiusPtr = *currentPtr;
441         *currentPtr = (*currentPtr)->nextList;
442     }
443 }

 

posted @ 2020-04-22 18:10  简单记录一下咯  阅读(175)  评论(0编辑  收藏  举报