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 = ;
//初始化链表
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语言 链表的创建--打印--逆置--新增--删除--排序--释放的更多相关文章
- C语言strrev()函数:字符串逆置(倒序、逆序)
头文件:#include<string.h> strrev()函数将字符串逆置,其原型为: char *strrev(char *str); [参数说明]str为要逆置的字符串. s ...
- C语言实现整数数组的逆置算法
读入100个整数到一个数组中,写出实现该数组进行逆置的算法. 方法一: 假设100个整数读入到数组a中,算法f1的思想是分别从数组两端依次将对应数进行交换,即a[i]与a[100 - i - 1]进行 ...
- leetcode 83. 删除排序链表中的重复元素 及 82. 删除排序链表中的重复元素 II
83. 删除排序链表中的重复元素 问题描述 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: ...
- C语言链表总结(创建,排序,增加,删除)
#include <stdio.h>#include <stdlib.h> typedef struct NODE{ int data ; struct NODE * pNex ...
- Leetcode:Swap Nodes in Pairs 单链表相邻两节点逆置
Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2-& ...
- 如何在时间复杂度为O(n)空间复杂度为O(1)的情况下完成链表的逆置
问题如题目,首先分析,链表的反转的空间复杂度如果为常数级,那么不可能完成从堆中申请数据来完成链表的反转工作,所以问题就转化为了如何将原链表修改/拆解为逆置的链表: 函数形式假定如下 void Inv ...
- YTU 2991: 链表节点逆置(线性表)
2991: 链表节点逆置(线性表) 时间限制: 1 Sec 内存限制: 128 MB 提交: 14 解决: 6 题目描述 设计一个算法,将一个带头节点的数据域依次为a1,a2,-,an(n> ...
- SDUT OJ 数据结构实验之链表三:链表的逆置
数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Descri ...
- SDUT-2118_数据结构实验之链表三:链表的逆置
数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入多个整数,以-1作为结束标志,顺序 ...
随机推荐
- File存储 - 文件存储
博客地址 http://www.cnblogs.com/mmyblogs/p/6107472.html(转载请保留) 文件存储 文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容 ...
- IOS开发-表单控件的应用
1. 需求描述 2. 开发环境介绍 3. 创建一个工程 4. 工程配置介绍 5. 目录结构介绍 6. 界面设置 7. 关联输入输出 8. 关联事件代码 9. 运行结果 10. UITextField ...
- iOS之 PJSIP静态库编译(三)
dada哪个所有静态库编译完成后还是不能运行那个demo,提示你找不到arm**.a 你lipo后要记得吧合并成.a 名字更改成你最后编译版本生成的.a名字....... 或者吧所有库add到你的工 ...
- Win7下:编译器错误信息: CS0016: 未能写入输出文件
错误如下: "/"应用程序中的服务器错误. 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS ...
- Javascript中的五种数据类型
Undefined 未定义.只有一个值undefined Null 只有一个值,null Boolean 在javascript中,只要逻辑表达式不返回undefined不返回null ...
- 使用Android studio创建的AIDL编译时找不到自定义类的解决办法
使用AS创建ADIL文件时AS会在main文件夹下给我们生成一个aidl文件夹和一个相同包名的包,通常我们会把所有和ADIL相关的类或文件放在这个包下,但是如果存在自定义的类时,程序编译时无法通过,提 ...
- redis客户端--jedis
一.jedis jedis 是 redis推荐的java客户端.通过Jedis我们可以很方便地使用java代码的方式,对redis进行操作.jedis使用起来比较简单,它的操作方法与redis命令相类 ...
- MyEclipse 6.5 代码自动提示功能配置教程
1. 打开MyEclipse 6.0.1,然后“window”→“Preferences” 2. 选择“java”,展开,“Editor”,选择“Content Assist”. 3. 选择“Cont ...
- cmd获取系统时间
查看时间格式: echo %date% echo %time% 通过%date:~5,2%来组合得出当前日期,组合的效果为yyyymmdd,date命令得到的日期格式默认为yyyy-mm-dd,通过% ...
- Linux学习之四——磁盘与文件系统管理
一.一些基本定义 1. superblock:记录此 filesystem 的整体信息,包括inode/block的总量.使用量.剩余量, 以及文件系统的格式与相关信息等:2. inode:记录档案的 ...