#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 = ;
//初始化链表
s1 = SList_Create(&len);
int res = ;
//打印链表
printf("\n------------s1打印链表--------------------\n");
res = PrintfAll(s1);
if (res != )
{
printf("s1打印链表程序出现错误!\n");
goto END;
}
//删除链表中指定节点
printf("\n------------s1链表逆置--------------------\n");
res = NoSort2(&s1);
if (res != )
{
printf("链表逆置程序出现错误!\n");
goto END;
}
//打印链表
printf("\n------------s1打印链表--------------------\n");
res = PrintfAll(s1);
if (res != )
{
printf("s2打印链表程序出现错误!\n");
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\n");
return NULL;
}
//定义链表头结点指针
Student * pHead = NULL, *pMalloc = NULL, *pCurrent = NULL, *pPrior = NULL;
int numx = , index = ;
while (){
printf("请输入学生的编号!\n");
scanf("%d", &numx);
if (numx == -)
{
break;
}
pCurrent = (Student *)malloc(sizeof(Student));
//注意这部分的内存释放
if (pCurrent==NULL)
{
printf("创建链表分配内存失败,释放已创建内存!\n");
FreeAll(&pHead);
}
memset(pCurrent, , 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\n");
return NULL;
}
//定义链表头结点指针
Student * pHead = NULL, *pMalloc = NULL, *pCurrent = NULL, *pNext = NULL;
int numx = , index = ;
while (){
printf("请输入学生的编号!\n");
scanf("%d", &numx);
if (numx == -)
{
break;
}
pCurrent = (Student *)malloc(sizeof(Student));
if (pCurrent == NULL)
{
printf("创建链表分配内存失败,释放已创建内存!\n");
FreeAll(&pHead);
}
memset(pCurrent, , 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 = ;
if (pin == NULL)
{
ERRO_MSG = ;
printf("pin==NULL erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
Student *pHead = NULL, *pCurrent = NULL;
pHead = pCurrent = pin;
while (pCurrent != NULL){
printf("%d\n", pCurrent->num);
pCurrent = pCurrent->pNext;
}
return ERRO_MSG;
} //链表排序
int Sort(Student *pin/*in*/, int *len/*in*/){
int ERRO_MSG = ;
if (pin == NULL || len == NULL)
{
ERRO_MSG = ;
printf("pin==NULL|| len==NULL erro msg :%d\n", 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 = ;
if (pin == NULL || len == NULL)
{
ERRO_MSG = ;
printf("pin == NULL || len==NULL erro msg:%d\n", ERRO_MSG);
return ERRO_MSG;
}
Student *pHead = NULL, *pPrior = NULL, *pCurrent = NULL, *pMalloc = NULL;
//创建指定元素
pMalloc = (Student *)malloc(sizeof(Student));
if (pMalloc == NULL)
{
ERRO_MSG = ;
printf("创建链表分配内存失败! erro msg:%d\n", 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 = ;
if (pin == NULL || pout == NULL)
{
ERRO_MSG = ;
printf("pin == NULL || pout==NULL erro msg:%d\n", 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 = ;
if (pin == NULL)
{
ERRO_MSG = ;
printf("pin == NULL erro msg:%d\n", 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 = ;
if (pin == NULL || len == NULL)
{
ERRO_MSG = ;
printf("pin == NULL || len==NULL erro msg:%d\n", 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 - ;
return ERRO_MSG;
} //释放内存
int FreeAll(Student **pin/*in*/){
int ERRO_MSG = ;
if (pin == NULL)
{
ERRO_MSG = ;
printf("pin==NULL erro msg:%d\n", 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;
}

C语言 链表的创建--打印--逆置--新增--删除--排序--释放的更多相关文章

  1. C语言strrev()函数:字符串逆置(倒序、逆序)

    头文件:#include<string.h> strrev()函数将字符串逆置,其原型为:    char *strrev(char *str); [参数说明]str为要逆置的字符串. s ...

  2. C语言实现整数数组的逆置算法

    读入100个整数到一个数组中,写出实现该数组进行逆置的算法. 方法一: 假设100个整数读入到数组a中,算法f1的思想是分别从数组两端依次将对应数进行交换,即a[i]与a[100 - i - 1]进行 ...

  3. leetcode 83. 删除排序链表中的重复元素 及 82. 删除排序链表中的重复元素 II

    83. 删除排序链表中的重复元素 问题描述 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: ...

  4. C语言链表总结(创建,排序,增加,删除)

    #include <stdio.h>#include <stdlib.h> typedef struct NODE{ int data ; struct NODE * pNex ...

  5. Leetcode:Swap Nodes in Pairs 单链表相邻两节点逆置

    Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...

  6. 如何在时间复杂度为O(n)空间复杂度为O(1)的情况下完成链表的逆置

    问题如题目,首先分析,链表的反转的空间复杂度如果为常数级,那么不可能完成从堆中申请数据来完成链表的反转工作,所以问题就转化为了如何将原链表修改/拆解为逆置的链表: 函数形式假定如下  void Inv ...

  7. YTU 2991: 链表节点逆置(线性表)

    2991: 链表节点逆置(线性表) 时间限制: 1 Sec  内存限制: 128 MB 提交: 14  解决: 6 题目描述 设计一个算法,将一个带头节点的数据域依次为a1,a2,-,an(n> ...

  8. SDUT OJ 数据结构实验之链表三:链表的逆置

    数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descri ...

  9. SDUT-2118_数据结构实验之链表三:链表的逆置

    数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入多个整数,以-1作为结束标志,顺序 ...

随机推荐

  1. DOM解析XML文件

    1.首先把第三方代码拖进工程 GDataXMLNode.h和GDataXMLNode.m这两个文件放进工程里面 2.引入libxml2库文件 3.将GDataXMLNode.h文件中的这两个东西在工程 ...

  2. AccessRandomFile多线程下载文件

    写一个工具类 package com.pb.thread.demo; import java.io.File; import java.io.FileNotFoundException; import ...

  3. IOS 杂笔-10(Base64 加密)

    base64加密是可逆的,因此并不是很安全,在一些注重安全的地方很少用到,但是在普通传输中可以使用. 切忌,base64加密是不安全的. // // ViewController.m // CX-Ba ...

  4. iOS之UI--CAGradientLayer

    1.CAGradientLayer 简介 如果说CAShapeLayer是用于提供设置形状的,那么CAGradientLayer是用于提供设置颜色的 英语单词:Gradient:梯度,渐变 那么Gra ...

  5. iOS证书失效

    iOS证书突然失效 今早上班打包直接报错,错误如图 根据错误信息到“钥匙串”里面看了一下证书,证书都莫名其妙的失效了,昨天还是好好的. 重新去钥匙串从证颁发中心获取证书,然后登陆开发者账号重新申请证书 ...

  6. maven 错误No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format

    [INFO] Scanning for projects... [INFO] ------------------------------------------------------------- ...

  7. SAM4E单片机之旅——21、DMAC之USART回显

    DMAC也可以和外设进行数据交互.之前我们曾使用PDC进行USART的数据回显,这次就使用DMAC完成相同的工作.而且由于DMAC有内部的缓冲区,实现起来更为简单. 一. USART设置 因为之前已经 ...

  8. OOD沉思录 --- 类和对象的关系 --- 包含关系2

    4.6 尽量让类中定义的每个方法尽可能多地使用包含的对象(即数据成员) 这其实就是高内聚的翻版强调.如果每个类的情况并非如此,那很可能是这一个类表示了两个或更多的概念,记住一个类只应该表示一个概念. ...

  9. 数据仓库建模与ETL实践技巧

    数据分析系统的总体架构分为四个部分 —— 源系统.数据仓库.多维数据库.客户端(图一:pic1.bmp) 其中,数据仓库(DW)起到了数据大集中的作用.通过数据抽取,把数据从源系统源源不断地抽取出来, ...

  10. php进程的SIGBUS故障

    某个子站是php写的,访问的时候nginx时不时会冒出现502错误,高峰时更频繁,检查php-fpm的日志发现大量的 child exited on signal 7 (SIGBUS),并且和acce ...