今天我们来学习一波有关链表的基本算法。
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<Windows.h> // 值类型 typedef int DataType; typedef struct SListNode { DataType data; // 值 struct SListNode *pNext; // 指向下一个结点 } SListNode; // 初始化 void SListInit(SListNode **ppFirst) { SListNode *pNode=*ppFirst; assert(ppFirst!=NULL); //初始化一个空链表。 pNode=NULL; } void SListsetup(DataType data) { SListNode *NewNode=(SListNode *)malloc(sizeof(SListNode)); assert(NewNode); NewNode->data=data; NewNode->pNext=NULL; } // 尾部插入 void SListPushBack(SListNode** ppFirst, DataType data) { SListNode *pNode; SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode)); //开辟一个空间,将data赋给它,并将pNext赋成NULL。 pNewNode->data=data; pNewNode->pNext=NULL; pNode=*ppFirst; //定义一个变量指向首元素。 if(pNode==NULL) { pNode->data=data; //可简写为 *pNode=pNewNode; pNode->pNext=NULL; } while(pNode->pNext!=NULL) { pNode=pNode->pNext; //循环得到最后一位数。将它的pNext赋值成data。 } pNode->pNext=pNewNode; free(pNewNode); //释放。 } // 头部插入 void SListPushFront(SListNode **ppFirst, DataType data) { SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode)); if(ppFirst==NULL) { //如果为空,就直接赋值。 pNewNode->data=data; pNewNode->pNext=NULL; } else{ pNewNode->data=data; //否则将开辟出来的空间的pNext赋值为原来第一个元素的地址。 pNewNode->pNext=*ppFirst; } free(pNewNode); } // 尾部删除 void SListPopBack(SListNode **ppFirst) { SListNode *pNode,*q; assert(ppFirst!=NULL); if((*ppFirst)->pNext==NULL) //如果只有一个元素,那就直接删除。 { free(*ppFirst); *ppFirst=NULL; } pNode=*ppFirst; while(pNode->pNext->pNext!=NULL) //这一步是为了找到倒数第二个数。将它的pNext赋值成NULL。 { pNode=pNode->pNext; } q=pNode->pNext; pNode->pNext=NULL; free(q); } // 头部删除 void SListPopFront(SListNode **ppFirst) { SListNode *pNode,*m; assert(ppFirst!=NULL); pNode=*ppFirst; m=pNode->pNext; free(pNode); *ppFirst=m; } // 给定结点插入,插入到结点前 void SListInsert(SListNode **ppFirst, SListNode *pPos, DataType data) { SListNode *pNode=*ppFirst; SListNode *pNewNode=(SListNode *)malloc(sizeof(SListNode)); assert(ppFirst!=NULL); pNewNode->pNext=pPos; pNewNode->data=data; //要插入的空间的data赋值data,pNext赋值为pPos。 if(*ppFirst==pPos) //如果第一个是指定节点就直接调用头插函数。 { SListPushFront(ppFirst,data); return; } while(pNode->pNext!=pPos) //循环找到给定节点前的那个数。 { pNode=pNode->pNext; } pNode->pNext=pNewNode; //将它的pNext赋值成要插入的值。 free(pNewNode); } // 给定结点删除 void SListErase(SListNode **ppFirst, SListNode *pPos) { SListNode *pNode=*ppFirst; if(*ppFirst==pPos) //如果给定节点为第一个,就直接调用头删函数。 { SListPopFront(ppFirst); return; } while(pNode->pNext!=pPos) //循环找到给定节点的上一个数。 { pNode=pNode->pNext; } pNode->pNext=pNode->pNext->pNext; //pNode->pNext=pPos->pNext free(pPos); } // 按值查找,返回第一个找到的结点指针,如果没找到,返回 NULL SListNode *SListFind(SListNode *pFirst, DataType data) { SListNode *pNode; assert(pFirst!=NULL); for(pNode=pFirst;pNode!=NULL;pNode=pNode->pNext) //循环寻找这个值第一次出现的位置。 { if(pNode->data==data) { return pNode; //找到返回它的节点指针,否则返回NULL。 } } return NULL; } // 按值删除,只删遇到的第一个 void SListRemove(SListNode **ppFirst, DataType data) { SListNode *pNode; assert(ppFirst!=NULL); pNode=SListFind(*ppFirst, data); //调用查找函数。 if(pNode==NULL) { printf("This data is not exit!\n"); //如果为NULL,则表示没这个值。 } else{ SListErase(ppFirst,pNode); //否则调用根据节点删除函数。 } } // 按值删除,删除所有的 void SListRemoveAll(SListNode **ppFirst, DataType data) { SListNode *pNode,*x; assert(ppFirst!=NULL); x=SListFind(*ppFirst, data); if(x==NULL) { printf("This data is not exit!\n"); } else{ for(pNode=*ppFirst;pNode!=NULL;pNode=pNode->pNext) //从头开始寻找与值一样的节点所在位置,然后分别删除它们。 { if(pNode->data==data) { SListErase(ppFirst,pNode); } } } } int SListSize(SListNode **ppFirst)//统计链表中一共有多少个数 { int size=0; SListNode *pNode=*ppFirst; for(;pNode!=NULL;pNode=pNode->pNext) //循环计算链表中有几个数。 { size++; } printf("The nnumber is %d\n",size); //输出结果。 return 0; } // 销毁 void SListDestroy(SListNode **ppFirst) { SListNode *r; SListNode *pNode=*ppFirst; for(;pNode!=NULL;pNode=r) { r=pNode->pNext; free(pNode); } *ppFirst=NULL; }
以上就是我所编写的算法,其中可能有很多错误,希望大家给些意见。