单链表-18个基本操作代码实现C语言
单链表-18个基本操作代码实现C语言
原文地址:https://www.cnblogs.com/actanble/p/6713434.html
无更改,仅复现
运行后如图,运行软件dev-C++,系统版本win10
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 6 typedef int elemType; //定义存入的数据的类型可以是 int char 7 8 typedef struct NODE{ //定义单链表的结点类型 9 elemType element; 10 struct NODE *next; 11 }Node; 12 13 /* 以下是关于线性表链接存储(单链表)操作的18种算法 */ 14 15 /* 1.初始化线性表,即置单链表的表头指针为空 */ 16 /* 2.创建线性表,此函数输入负数终止读取数据*/ 17 /* 3.打印链表,链表的遍历*/ 18 /* 4.清除线性表L中的所有元素,即释放单链表L中所有的结点,使之成为一个空表 */ 19 /* 5.返回单链表的长度 */ 20 /* 6.检查单链表是否为空,若为空则返回1,否则返回0 */ 21 /* 7.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行 */ 22 /* 8.从单链表中查找具有给定值x的第一个元素,若查找成功则返回该结点data域的存储地址,否则返回NULL */ 23 /* 9.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0 */ 24 /* 10.向单链表的表头插入一个元素 */ 25 /* 11.向单链表的末尾添加一个元素 */ 26 /* 12.向单链表中第pos个结点位置插入元素为x的结点,若插入成功返回1,否则返回0 */ 27 /* 13.向有序单链表中插入元素x结点,使得插入后仍然有序 */ 28 /* 14.从单链表中删除表头结点,并把该结点的值返回,若删除失败则停止程序运行 */ 29 /* 15.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行 */ 30 /* 16.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行 */ 31 /* 17.从单链表中删除值为x的第一个结点,若删除成功则返回1,否则返回0 */ 32 /* 18.交换2个元素的位置 */ 33 /* 19.将线性表进行快速排序 */ 34 35 /*************************************************************************************************/ 36 37 38 39 40 41 /*1,初始化线性表,即置单链表的表头为空*/ 42 void initList(Node **pNode){ 43 *pNode=NULL; 44 printf("inirList函数执行,初始化成功!\n"); 45 } 46 47 /*2,创建线性表,此函数输入负数终止读取数据*/ 48 Node *creatList(Node *pHead){ 49 50 Node *p1,*p2; 51 p1=p2=(Node *)malloc(sizeof(Node));//生成新的头结点,p1、p2两个头指针指向头结点 52 if(p1==NULL||p2==NULL){ 53 printf("内存分配失败\n"); 54 exit(0); 55 } 56 memset(p1,0,sizeof(Node)); 57 58 scanf("%d",&p1->element); 59 p1->next=NULL; 60 61 while(p1->element >0){ //输入的大于0则继续否则停止 62 if(pHead==NULL){//空表,接入表头 63 pHead=p1; 64 } 65 else{ 66 p2->next=p1; 67 } 68 69 p2=p1; 70 p1=(Node *)malloc(sizeof(Node)); 71 72 if(p1==NULL||p2==NULL){ 73 printf("内存分配失败\n"); 74 exit(0); 75 } 76 memset(p1,0,sizeof(Node)); 77 scanf("%d",&p1->element); 78 p1->next=NULL; 79 80 } 81 printf("CreatList函数执行,链表创建成功\n"); 82 return pHead; 83 } 84 /*3,打印链表,链表的遍历*/ 85 void printList(Node *pHead){ 86 if(NULL==pHead){ 87 printf("PrintList函数执行,链表为空\n"); 88 } 89 else{ 90 while(NULL!=pHead){ 91 printf("%d",pHead->element); 92 pHead=pHead->next; 93 } 94 printf("\n"); 95 } 96 } 97 98 /*4,清楚线性表中的所有元素,几释放单链表中的所有节点,使表为空,null*/ 99 void clearList(Node *pHead){ 100 101 Node *pNext; 102 103 if(pHead==NULL){ 104 printf("clearListh函数执行,链表为空"); 105 return; 106 } 107 while (pHead->next!=NULL){ 108 pNext=pHead->next; 109 free(pHead); 110 pHead=pNext; 111 } 112 printf("clearList函数执行,链表已经清除"); 113 } 114 115 /*5,返回链表的长度*/ 116 int sizeList(Node *pHead){ 117 int size=0; 118 119 while(pHead!=NULL){ 120 size++; 121 pHead=pHead->next; 122 } 123 printf("sizeList函数执行,链表的长度为%d\n",size); 124 return size; 125 } 126 127 /*6,检擦链表是否为空,若空返回1,否则返回0*/ 128 int isEmptyList(Node *pHead){ 129 if(pHead==NULL){ 130 printf("isEmptyList函数执行,链表为空"); 131 return 1; 132 } 133 else{ 134 printf("isEmptyList函数执行,链表非空"); 135 return 0; 136 } 137 } 138 /*7,按位置查找,返回链表中第post节点的数据,若post超出范围,则停止程序运行*/ 139 int getElement(Node *pHead,int pos){ 140 int i=0; 141 if(pos<1){ 142 printf("getElemnet函数执行,pos值非法!"); 143 return 0; 144 } 145 if(pHead==NULL){ 146 printf("getElemnet函数执行,链表为空"); 147 } 148 while(pHead&&i!=pos){ 149 i++; 150 pHead=pHead->next; 151 } 152 if(!pHead||i<pos){ 153 printf("getElement函数执行,pos值超出表的长度\n"); 154 return 0; 155 } 156 printf("getElement函数执行,位置%d中的元素位置为%d\n",pos,pHead->element); 157 return 1; 158 159 } 160 /*从单一俩表中查找具有得顶值x的第一个元素,成功则返回改结点data域的存储位置,否则返回NULL*/ 161 elemType *getElemAddr(Node *pHead,elemType x){ 162 163 if(NULL==pHead){ 164 printf("getEleAddr函数执行,链表为空"); 165 return NULL; 166 } 167 if(x<0){ 168 printf("getEleArdd函数执行,给定值X不合法\n"); 169 return NULL; 170 } 171 while((pHead->element!=x)&&(NULL!=pHead->next)){//判断链表是否为空,并且是否存在查找的元素 172 pHead=pHead->next; 173 } 174 if (pHead->element!=x){ 175 printf("getElemAddr函数执行,在链表中没有找到x的值\n"); 176 return NULL; 177 } 178 else{ 179 printf("getElemAddr函数执行,元素%d的地址为0x%x\n",x,&(pHead->element)); 180 181 } 182 return &(pHead->element); 183 } 184 /*9,修改链表中第pos个点x的值,修改成功返回1,否则返回0*/ 185 int modifyElem(Node *pNode,int pos,elemType x){ 186 187 Node *pHead; 188 pHead=pNode; 189 int i=0; 190 if(NULL==pHead){ 191 printf("modityElem函数执行,链表为空"); 192 return 0; 193 } 194 if(pos<1){ 195 printf("modityElem函数执行,pos值非法\n"); 196 return 0; 197 } 198 if(pos>i){ 199 printf("modityElem函数执行,pos值超过链表长度\n"); 200 return 0; 201 } 202 while(pHead!=NULL){ 203 204 ++i; 205 if(i==pos){ 206 break; 207 } 208 pHead=pHead->next; 209 } 210 pNode=pHead; 211 pNode->element=x; 212 printf("modifyElem函数执行,修改第%d点的元素为%d\n",pos,x); 213 return 1; 214 215 } 216 217 218 219 220 221 222 /*10,向单链表的表头插入一个元素*/ 223 int insertHeadList(Node **pNode,elemType insertElem){ 224 225 Node *pInsert; 226 pInsert=(Node *)malloc(sizeof(Node)); 227 if(pInsert==NULL) exit(1); 228 memset(pInsert,0,sizeof(Node)); 229 pInsert->element=insertElem; 230 pInsert->next=*pNode; 231 *pNode=pInsert; 232 printf("insertHeadList函数执行,向单链表的表头插入元素%d成功\n",insertElem); 233 return 1; 234 } 235 /*11,向单链表的队尾添加一个元素*/ 236 int insertLastList(Node *pNode,elemType insertElem){ 237 238 Node *pInsert; 239 Node *pHead; 240 Node *pTmp; 241 242 pHead=pNode; 243 pTmp=pHead; 244 pInsert=(Node *)malloc(sizeof(Node)); 245 if(pInsert==NULL) exit(1); 246 memset(pInsert,0,sizeof(Node)); 247 pInsert->element=insertElem; 248 pInsert->next=NULL; 249 while(pHead->next!=NULL){ 250 251 pHead=pHead->next; 252 } 253 pHead->next=pInsert; 254 printf("insertLastList函数执行,向单链表的队尾添加元素%d成功\n",insertElem); 255 return 1; 256 } 257 /*12,向单链表中的第pos个节点插入元素为x的节点,成功返回1,否则后返回0*/ 258 int isAddPos(Node *pNode,int pos,elemType x){ 259 260 Node *pHead; 261 pHead=pNode; 262 Node *pTmp; 263 int i=0; 264 265 if(NULL==pHead){ 266 printf("AddPos函数执行,链表为空"); 267 return 0; 268 } 269 if(pos<1){ 270 printf("AddPos函数执行,pos值非法"); 271 return 0; 272 } 273 while(pHead!=NULL){ 274 ++i; 275 if(i==pos){ 276 break; 277 } 278 pHead=pHead->next; 279 } 280 if(i<pos){ 281 printf("AddPos函数执行,pos值超出链表的长度"); 282 return 0; 283 } 284 pTmp=(Node *)malloc(sizeof(Node)); 285 if(pTmp==NULL) exit(1); 286 memset(pTmp,0,sizeof(Node)); 287 pTmp->next=pHead->next; 288 pHead->next=pTmp; 289 pTmp->element=x; 290 291 printf("AddPos函数执行成功,像结点%d后插入数值%d\n",pos,x); 292 return 1; 293 } 294 /*13,向单链表插入元素x节点,是的插入后仍有序*/ 295 int OrrderList(Node *pNode,elemType x){ 296 //注意如果此数值要排到行尾要修改本代码 297 Node *pHead=pNode; 298 pHead=pNode; 299 Node *pTmp; 300 301 if(NULL==pHead){ 302 printf("OrrderList函数执行,链表为空\n"); 303 return 0; 304 } 305 if(x<1){ 306 printf("OrrderList函数执行,x值非法\n"); 307 return 0; 308 } 309 while(pHead!=NULL){ 310 if((pHead->element)>x){ 311 break; 312 } 313 pHead=pHead->next; 314 } 315 if(pHead==NULL){ 316 printf("OrrderList函数执行,该函数中没有该值\n"); 317 return 0; 318 } 319 320 pTmp=(Node *)malloc(sizeof(Node)); 321 if(pTmp==NULL) exit(1); 322 memset(pTmp,0,sizeof(Node)); 323 pTmp->next=pHead->next; 324 pHead->next=pTmp; 325 pTmp->element=x; 326 327 printf("OrrderList函数成功插入数值%d\n",x); 328 return 1; 329 } 330 /*14,从单链表中删除头结点并返回其值,失败则停止程序运行*/ 331 int DelHeadList(Node **pList){ 332 333 Node *pHead; 334 pHead=*pList; 335 if(pHead!=NULL){ 336 printf("DelHeadList函数执行,函数首元素为%d删除成功\n",pHead->element); 337 } 338 else{ 339 printf("DelHeadList函数执行,俩鸟为空"); 340 return 0; 341 } 342 *pList=pHead->next; 343 return 1; 344 } 345 /*15,从链表中删除表尾节点并返回其值,若失败停止程序运行*/ 346 int DelLastList(Node *pNode){ 347 348 Node *pHead; 349 Node *pTmp; 350 351 pHead=pNode; 352 while(pHead->next!=NULL){ 353 354 pTmp=pHead; 355 pHead=pHead->next; 356 } 357 printf("链表尾删除原元素%d成功\n",pHead->element); 358 free(pHead); 359 pTmp->next=NULL; 360 return 1; 361 } 362 /*16,从链表中删除第pos个结点并返回他的值,失败则停止程序运行*/ 363 int DelPos(Node *pNode,int pos){ 364 365 Node *pHead; 366 pHead=pNode; 367 Node *pTmp; 368 int i=0; 369 370 if(NULL==pHead){ 371 printf("DelPos函数执行,链表为空"); 372 return 0; 373 } 374 if(pos<1){ 375 printf("DlePos函数之心,pos值非法"); 376 return 0; 377 } 378 while(pHead!=NULL){ 379 ++i; 380 if(i==pos){ 381 break; 382 } 383 pTmp=pHead; 384 pHead=pHead->next; 385 } 386 if(i<pos){ 387 printf("DelPos函数执行,pos值超出链表长度"); 388 return 0; 389 } 390 printf("DelPos函数执行成功,结点%d删除数值%d\n",pos,pHead->element); 391 return 1; 392 } 393 /*17,从单链表中删除值为x的第一个结点,若删除成功返回1, 否则返回0*/ 394 int Dlex(Node **pNode,int x){ 395 396 Node *pHead; 397 Node *pTmp; 398 pHead=*pNode; 399 int i=0; 400 401 if(NULL==pHead){ 402 printf("Delx函数执行,链表为空"); 403 return 0; 404 } 405 if(x<0){ 406 printf("Delx函数执行,给定值x不合法\n"); 407 return 0; 408 } 409 while((pHead->element!=x)&&(NULL!=pHead->next)){ 410 411 i++; 412 pTmp=pHead; 413 pHead=pHead->next; 414 415 } 416 if(pHead->element!=x){ 417 printf("Delx函数执行,在链表中没有找到x值\n"); 418 return 0; 419 } 420 if((i==0)&&(NULL!=pHead->next)){ 421 printf("Delx函数执行,在链表首部找到此袁术,此袁术已经被删除"); 422 free(pHead); 423 return 1; 424 } 425 printf("Delx函数执行首个为%d元素被删除\n"); 426 free(pHead); 427 return 1; 428 } 429 /*18,交换两个元素的位置*/ 430 int exchange2pos(Node *pNode,int pos1,int pos2){ 431 432 Node *pHead; 433 int *pTmp; 434 int *pInsert; 435 int a; 436 int i=0; 437 438 if(pos1<1||pos2<1){ 439 printf("DelPos函数执行,pos值非法\n"); 440 return 0; 441 } 442 pHead=pNode; 443 while(pHead!=NULL){ 444 ++i; 445 if(i==pos1){ 446 break; 447 } 448 pHead=pHead->next; 449 450 } 451 if(i<pos1){ 452 printf("DelPos函数执行,pos1值超出链表长度\n"); 453 return 0; 454 } 455 pTmp=&(pHead->element); 456 i=0; 457 pHead=pNode; 458 while(pHead!=NULL){ 459 ++i; 460 if(i==pos2){ 461 break; 462 } 463 pHead=pHead->next; 464 } 465 if(i<pos2){ 466 printf("DelPos函数执行,pos2值超出链表长度\n"); 467 return 0; 468 } 469 pInsert=&(pHead->element); 470 a=*pTmp; 471 *pTmp=*pInsert; 472 *pInsert=a; 473 474 printf("DelPos函数执行,交换第%d个和第%d个点的值\n",pos1,pos2); 475 return 1; 476 } 477 478 int swap(int *p1,int *p2){ 479 int a; 480 if(*p1>*p2){ 481 a=*p1; 482 *p1=*p2; 483 *p2=a; 484 } 485 return 0; 486 } 487 488 /*19,将链表进行冒泡排序*/ 489 int Arrange(Node *pNode){ 490 491 Node *pHead; 492 pHead=pNode; 493 494 int a=0,i,j; 495 if(NULL==pHead){ 496 printf("Arrange函数执行,链表为空\n"); 497 return 0; 498 } 499 while(pHead!=NULL){ 500 ++a; 501 pHead=pHead->next; 502 } 503 504 pHead=pNode; 505 for(i=0;i<a-1;i++){ 506 507 for(j=1;j<a-i;j++){ 508 swap(&(pHead->element),&(pHead->next->element)); 509 pHead=pHead->next; 510 } 511 pHead=pNode; 512 } 513 printf("Arrange函数执行,链表排序完毕!\n"); 514 return 0; 515 } 516 517 518 519 520 int main() 521 { 522 Node *pList=NULL; 523 int length=0; 524 525 elemType posElem; 526 527 initList(&pList); 528 printList(pList); 529 530 pList=creatList(pList); 531 printList(pList); 532 533 sizeList(pList); 534 printList(pList); 535 536 isEmptyList(pList); 537 538 539 posElem=getElement(pList,3); 540 printList(pList); 541 542 getElemAddr(pList,5); 543 544 modifyElem(pList,4,1); 545 printList(pList); 546 547 548 insertHeadList(&pList,5); 549 printList(pList); 550 551 insertLastList(pList,6); 552 printList(pList); 553 554 555 isAddPos(pList,4,5); 556 printList(pList); 557 558 559 OrrderList(pList,6); 560 printList(pList); 561 562 563 DelHeadList(&pList); 564 printList(pList); 565 566 567 DelLastList(pList); 568 printList(pList); 569 570 571 DelPos(pList,3); 572 printList(pList); 573 574 575 Dlex(&pList,5); 576 printList(pList); 577 578 579 exchange2pos(pList,2,5); 580 printList(pList); 581 582 Arrange(pList); 583 printList(pList); 584 585 clearList(pList); 586 return 0; 587 588 }
总结:
进一步理解怎样构造函数、调用、函数之间的关系。
memset函数与L=(linklist)malloc(sizeof(Node))作用?
malloc函数:
L=(linklist)malloc(sizeof(Node))作用是生成一个新结点做头结点,头指针L指向头结点
memset函数:
void * memset (void * p,int c,size_t n);
其中,指针p为所操作的内存空间的首地址,c为每个字节所赋的值,n为所操作内存空间的字节长度,也就是内存被赋值为c的字节数。
在使用memset时经常要注意的它是以字节为单位进行赋值的,所赋值的范围是0x00~0xFF。若想要对一个double或int型的数组赋值时,就特别需要注意这一点: