简单链表操作
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 }