#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> //定义结构体 typedef struct _student{ int num; struct _student *pNext; }Student; //创建链表(顺序创建链表) Student * SList_Create(int *len/*out*/); //创建链表(逆序创建链表) Student * SList_Create2(int *len/*out*/); //打印链表 int PrintfAll(Student *pin/*in*/); //链表排序 int Sort(Student *pin/*in*/, int *len/*in*/); //插入指定位置节点 int InsertOption(int numx/*in*/, Student *pin/*in*/, int *len/*out*/); //链表顺序逆置 int NoSort(Student *pin/*in*/, Student **pout/*out*/); //链表顺序逆置2 int NoSort2(Student **pin/*in*/); //删除指定节点 int RemoveNode(int numx/*in*/, Student *pin/*in*/, int *len/*out*/); //释放内存 int FreeAll(Student **pin/*in*/); void main(){ Student *s1 = NULL, *s2 = NULL; //定义链表长度 int len = 0; //初始化链表 s1 = SList_Create(&len); int res = 0; //打印链表 printf(" ------------s1打印链表-------------------- "); res = PrintfAll(s1); if (res != 0) { printf("s1打印链表程序出现错误! "); goto END; } //删除链表中指定节点 printf(" ------------s1链表逆置-------------------- "); res = NoSort2(&s1); if (res != 0) { printf("链表逆置程序出现错误! "); goto END; } //打印链表 printf(" ------------s1打印链表-------------------- "); res = PrintfAll(s1); if (res != 0) { printf("s2打印链表程序出现错误! "); goto END; } END: //释放链表内存 if (s1 != NULL) { FreeAll(&s1); } if (s2 != NULL) { FreeAll(&s2); } system("pause"); } //创建链表(顺序创建链表) Student * SList_Create(int *len/*in*/){ if (len == NULL) { printf("不可以为NULL "); return NULL; } //定义链表头结点指针 Student * pHead = NULL, *pMalloc = NULL, *pCurrent = NULL, *pPrior = NULL; int numx = 0, index = 0; while (1){ printf("请输入学生的编号! "); scanf("%d", &numx); if (numx == -1) { break; } pCurrent = (Student *)malloc(sizeof(Student));
//注意这部分的内存释放 if (pCurrent==NULL) { printf("创建链表分配内存失败,释放已创建内存! "); FreeAll(&pHead); } memset(pCurrent, 0, sizeof(Student)); pCurrent->num = numx; pCurrent->pNext = NULL; if (pPrior != NULL) { pPrior->pNext = pCurrent; pPrior = pCurrent; } else{ pHead = pPrior = pCurrent; } index++; } *len = index; return pHead; } //创建链表(逆序创建链表) Student * SList_Create2(int *len/*in*/){ if (len == NULL) { printf("链表的长度不可以为NULL "); return NULL; } //定义链表头结点指针 Student * pHead = NULL, *pMalloc = NULL, *pCurrent = NULL, *pNext = NULL; int numx = 0, index = 0; while (1){ printf("请输入学生的编号! "); scanf("%d", &numx); if (numx == -1) { break; } pCurrent = (Student *)malloc(sizeof(Student)); if (pCurrent == NULL) { printf("创建链表分配内存失败,释放已创建内存! "); FreeAll(&pHead); } memset(pCurrent, 0, sizeof(Student)); pCurrent->num = numx; pCurrent->pNext = pNext; pNext = pCurrent; index++; } pHead = pCurrent; *len = index; return pHead; } //打印链表 int PrintfAll(Student *pin/*in*/){ int ERRO_MSG = 0; if (pin == NULL) { ERRO_MSG = 1; printf("pin==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Student *pHead = NULL, *pCurrent = NULL; pHead = pCurrent = pin; while (pCurrent != NULL){ printf("%d ", pCurrent->num); pCurrent = pCurrent->pNext; } return ERRO_MSG; } //链表排序 int Sort(Student *pin/*in*/, int *len/*in*/){ int ERRO_MSG = 0; if (pin == NULL || len == NULL) { ERRO_MSG = 1; printf("pin==NULL|| len==NULL erro msg :%d ", ERRO_MSG); return ERRO_MSG; } //定义链表变量 Student *pHead = NULL, *pPrior = NULL, *pCurrent = NULL, *pNext = NULL; //接收链表变量 pCurrent = pin; //冒泡排序 //分析:两种方案①是调换链表元素的指针,但是操作复杂,理解麻烦,而且这个环境里,结构体并不是很大(如果结构体比较大,那么推荐使用指针替换),复杂的逻辑不适合 //②调换链表元素的值,这个方案比较简单 //链表一般使用while,因为不知道链表的个数 //获取链表中实际元素的个数,方便冒泡排序,(冒泡排序循环的次数和元素的个数有关) int numx = *len; while (numx){ //将最大的元素扔到末尾 //重置pCurrent pPrior = pCurrent = pin; while (pCurrent != NULL){ if (pPrior != pCurrent) { if (pPrior->num>pCurrent->num) { numx = pPrior->num; pPrior->num = pCurrent->num; pCurrent->num = numx; } } pPrior = pCurrent; pCurrent = pCurrent->pNext; } numx--; } return ERRO_MSG; } //插入指定位置节点 int InsertOption(int numx/*in*/, Student *pin/*in*/, int *len/*out*/){ int ERRO_MSG = 0; if (pin == NULL || len == NULL) { ERRO_MSG = 1; printf("pin == NULL || len==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Student *pHead = NULL, *pPrior = NULL, *pCurrent = NULL, *pMalloc = NULL; //创建指定元素 pMalloc = (Student *)malloc(sizeof(Student)); if (pMalloc == NULL) { ERRO_MSG = 2; printf("创建链表分配内存失败! erro msg:%d ", ERRO_MSG); return ERRO_MSG; } pMalloc->num = numx; pMalloc->pNext = NULL; pCurrent = pPrior = pin; //思路:找到目标节点的当前节点和前一个节点,比较指定元素是否比连表中元素大 //先比较第一个元素和指定元素的大小 if (pCurrent->num>pMalloc->num) { pMalloc->pNext = pCurrent; pin = pMalloc; } else{ //遍历链表 while (pCurrent != NULL){ if (pPrior != pCurrent) { if (pMalloc->num<pCurrent->num) { //把这个节点插入到链表中 pPrior->pNext = pMalloc; pMalloc->pNext = pCurrent; break; } } pPrior = pCurrent; pCurrent = pCurrent->pNext; } } *len++; return ERRO_MSG; } //链表顺序逆置 int NoSort(Student *pin/*in*/, Student **pout/*out*/){ int ERRO_MSG = 0; if (pin == NULL || pout == NULL) { ERRO_MSG = 1; printf("pin == NULL || pout==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Student *pCurrent = NULL; Student *pHead2 = NULL, *pCurrent2 = NULL, *pNext2 = NULL; pCurrent = pin;; while (pCurrent != NULL){ pCurrent2 = (Student *)malloc(sizeof(Student)); pCurrent2->num = pCurrent->num; pCurrent2->pNext = pNext2; pNext2 = pCurrent2; pCurrent = pCurrent->pNext; } pHead2 = pCurrent2; *pout = pHead2; return ERRO_MSG; } //链表顺序逆置2 int NoSort2(Student **pin/*in*/){ int ERRO_MSG = 0; if (pin == NULL) { ERRO_MSG = 1; printf("pin == NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Student *pHead = NULL, *pCurrent = NULL, *pNext = NULL, *pPrior = NULL; pCurrent = pPrior = *pin; pNext = pCurrent->pNext; pPrior->pNext = NULL; if (pCurrent->pNext=NULL) { return ERRO_MSG; } while (pCurrent){ if (pCurrent != pPrior) { //下一个节点 pNext = pCurrent->pNext; pCurrent->pNext = pPrior; } pPrior = pCurrent; pCurrent = pNext; } pHead = pPrior; *pin = pHead; return ERRO_MSG; } //删除指定节点 int RemoveNode(int numx/*in*/, Student *pin/*in*/, int *len/*out*/){ int ERRO_MSG = 0; if (pin == NULL || len == NULL) { ERRO_MSG = 1; printf("pin == NULL || len==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } //定义链表变量 Student *pHead = NULL, *pCurrent = NULL, *pNext = NULL, *pPrior = NULL; pPrior = pCurrent = pin; //判断第一个节点 if (pCurrent->num == numx) { pHead = pCurrent->pNext; //释放该节点 free(pCurrent); } else{ //遍历链表 while (pCurrent != NULL){ if (pCurrent != pPrior) { if (pCurrent->num == numx) { pPrior->pNext = pCurrent->pNext; //释放该节点 free(pCurrent); pCurrent = NULL; pCurrent = pPrior->pNext; continue; } } pPrior = pCurrent; pCurrent = pCurrent->pNext; } } *len = *len - 1; return ERRO_MSG; } //释放内存 int FreeAll(Student **pin/*in*/){ int ERRO_MSG = 0; if (pin == NULL) { ERRO_MSG = 1; printf("pin==NULL erro msg:%d ", ERRO_MSG); return ERRO_MSG; } Student *pHead = NULL, *pCurrent = NULL, *pNext = NULL; pHead = *pin; pCurrent = pHead; if (pCurrent != NULL) { while (pCurrent != NULL){ pNext = pCurrent->pNext; //释放内存 free(pCurrent); pCurrent = pNext; } } //避免野指针 *pin = NULL; return ERRO_MSG; }