C语言 链表的创建--打印--逆置--新增--删除--排序--释放

#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; }

原文地址:https://www.cnblogs.com/zhanggaofeng/p/5526535.html