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, ¤t1Ptr);
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, ¤t2Ptr);
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 }