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作为结束标志,顺序 ...
随机推荐
- C安全编码--整数理解
建议和规则 建议: 理解编译器所使用的数据模型 使用rsize_t或size_t类型表示所有表示对象长度的整数值 理解整数转换规则 使用安全的整数库 对来自不信任来源的整数值实行限制 如果输入函数无法 ...
- 百度Couldn't load BaiduMapSDK_v2_4_1 from loader dalvik
原文链接:http://liuzhichao.com/p/1463.html 在使用百度定位SDK的时候,明明已经加入了liblocSDK3.so,Manifest中也添加了相应权限,注册了com.b ...
- SQL JOIN
- Spring(九)Spring对事务的支持
一.对事务的支持 事务:是一组原子操作的工作单元,要么全部成功,要么全部失败 Spring管理事务方式: JDBC编程事务管理:--可以控制到代码中的行 可以清楚的控制事务的边界,事务控制粒度化细(编 ...
- Objective-C之优雅的命名
There are only two hard things in Computer Science: cache invalidation and naming things.在计算机科学中只有两件 ...
- git 查看远程分支、本地分支、删除本地分支
1 查看远程分支 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ git branch -a * br-2.1.2.2 master remotes/origi ...
- Android中TextView中的文字设置为不同颜色
questionDesTextView=(TextView)findViewById(R.id.question_des); SpannableStringBuilder builder = new ...
- OC语言-01-面向过程与面向对象思想
一.面向过程 1> 思想 面向过程是一种以过程为中心的最基础编程思想,不支持面向对象的特性. 面向过程是一种模块化程序设计方法 2> 开发方法 面向过程的开发方法是以过程(也可以说是模块) ...
- Mac OS X 10.10 Yosemite下面解决XAMPP无法开启mysql的问题
首次使用XAMPP但是却遇到一个MySQL无法启动的缘故,不知道怎么解决,经过百度 找到解决方案: 在xampp安装目录下找到xamp这个文件(默认路径是:/Applications/XAMPP/xa ...
- 忙碌的Nova君 (活动安排问题、贪心算法)
题目描述 理论上,Nova君是个大闲人,但每天还是有一大堆事要干,大作业啦,创新杯啦,游戏啦,出题坑人啦,balabala......然而精力有限,Nova君同一时间只能做一件事,并不能一心二用.假设 ...