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

  • 相关阅读:
    css引入讲解及media
    css中的media
    IE6存在的一些兼容
    Eclipse 反编译插件JadClipse安装
    JavaScript 常用功能总结
    241个jquery插件—jquery插件大全
    javascript深入理解js闭包
    JS拖拽插件实现步骤
    JavaScript拖拽原理的实现
    js实现拖拽效果
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5526535.html
Copyright © 2020-2023  润新知