您的位置:首页 > 编程语言 > C语言/C++

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

2016-05-25 12:13 513 查看
#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("\n------------s1打印链表--------------------\n");
res = PrintfAll(s1);
if (res != 0)
{
printf("s1打印链表程序出现错误!\n");
goto END;
}
//删除链表中指定节点
printf("\n------------s1链表逆置--------------------\n");
res = NoSort2(&s1);
if (res != 0)
{
printf("链表逆置程序出现错误!\n");
goto END;
}
//打印链表
printf("\n------------s1打印链表--------------------\n");
res = PrintfAll(s1);
if (res != 0)
{
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 = 0, index = 0;
while (1){
printf("请输入学生的编号!\n");
scanf("%d", &numx);
if (numx == -1)
{
break;
}
pCurrent = (Student *)malloc(sizeof(Student));
//注意这部分的内存释放
if (pCurrent==NULL)
{
printf("创建链表分配内存失败,释放已创建内存!\n");
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\n");
return NULL;
}
//定义链表头结点指针
Student * pHead = NULL, *pMalloc = NULL, *pCurrent = NULL, *pNext = NULL;
int numx = 0, index = 0;
while (1){
printf("请输入学生的编号!\n");
scanf("%d", &numx);
if (numx == -1)
{
break;
}
pCurrent = (Student *)malloc(sizeof(Student));
if (pCurrent == NULL)
{
printf("创建链表分配内存失败,释放已创建内存!\n");
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\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 = 0;
if (pin == NULL || len == NULL)
{
ERRO_MSG = 1;
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 = 0;
if (pin == NULL || len == NULL)
{
ERRO_MSG = 1;
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 = 2;
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 = 0;
if (pin == NULL || pout == NULL)
{
ERRO_MSG = 1;
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 = 0;
if (pin == NULL)
{
ERRO_MSG = 1;
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 = 0;
if (pin == NULL || len == NULL)
{
ERRO_MSG = 1;
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 - 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\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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: