[C语言]数据结构之单链表

简介

本文将实现单链表的基础接口功能
1.初始化/销毁
2.增删改查
头文件.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
typedef int SLDataType;
typedef struct SListNode{
	SLDataType data;
	struct SListNode *next;
} SListNode;

typedef struct SList{
	 struct SListNode *first;//first{? , next}
}SList;

//接口
//初始化/销毁
void SListInit(SList *list);
void SListDestroy(SList *list);
//增/删/查/改
//头插
void SListPushFront(SList *list, SLDataType data);
//头删
void SListPopFront(SList *list);

//尾插
void SListPushBack(SList *list, SLDataType data);
//尾删
void SListPopBack(SList *list);

//查找
SListNode *SListFind(SList *list, SLDataType data);

//在pos结点后面插入
void SListInsertAfter(SListNode *pos, SLDataType data);

//删除pos结点后面的结点
void SListEraseAfter(SListNode *pos);

//删除第一个遇到的data结点
void SListRemove(SList *list, SLDataType data);

//打印
void SListPrint(SList *list);

函数实现部分SList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

void SListInit(SList *list)
{
	 assert(list != NULL);
	 list->first = NULL;
}

void SListDestroy(SList *list)
 {
	  SListNode *next;
	  for (SListNode *cur = list->first; cur != NULL; cur = next){
		   next = cur->next;
		   free(cur);
	  }
	  list->first = NULL;
 }

//创建空间
SListNode *BuySListNode(SLDataType data)
{
	 //然后创建一个结点
	 SListNode *node = (SListNode *)malloc(sizeof(SListNode));
	 assert(node != NULL);
	 //赋值
	 node->data = data;
	 node->next = NULL;
	 return node;
}

//头插
void SListPushFront(SList *list, SLDataType data)
{
	 assert(list != NULL);
	 //1.Node 空间
	 //SListNode *node = (SListNode *)malloc(sizeof(SListNode));
	 //assert(node);
	 2.赋值
	 //node->data = data;
	 //3.新的第一个结点的下一个结点就是原来的第一个结点
	 SListNode *node = BuySListNode(data);
	 node->next = list->first;
	 //4.记录新的第一个结点
	 list->first = node;
}

//头删
void SListPopFront(SList *list)
{
	 assert(list != NULL); //没有链表
	 assert(list->first != NULL);//有链表但是链表是空的,排除一开始一个结点都没有
	 SListNode *old_first = list->first;
	 list->first = list->first->next;
	 free(old_first);
}

//尾插
void SListPushBack(SList *list, SLDataType data)
{
	 //没有链表
	 assert(list != NULL);
	 //链表为空的情况就是头插
	 if (list->first == NULL){
		  SListPushFront(list, data);
		  //头插完记得返回
		  return;
	 }
	 //先找出最后一个结点
	 SListNode *cur = list->first;
	 for (; cur->next != NULL; cur = cur->next){
	 }
	 然后创建一个结点
	 //SListNode *node = (SListNode *)malloc(sizeof(SListNode));
	 //assert(node != NULL);
	 赋值
	 //node->data = data;
	 //node->next = NULL;
	 SListNode *node = BuySListNode(data);
	 cur->next = node;
}

//尾删
void SListPopBack(SList *list)
{
	 assert(list != NULL);
	 //链表为空
	 assert(list->first != NULL);
	 //链表只有一个结点就用头删
	 if (list->first->next == NULL){
		  SListPopFront(list);
		  return;
	 }
	 //找到倒数第二个结点
	 SListNode *cur = list->first;
	 for (; cur->next->next != NULL; cur = cur->next){
	 }
	 //先释放,再指向空
	 free(cur->next);
	 cur->next = NULL;
}

//查找
SListNode *SListFind(SList *list, SLDataType data)
{
	 for (SListNode *cur = list->first; cur != NULL; cur = cur->next){
		  if (cur->data == data){
		  	 return cur;
		  }
	 }
	 return NULL;
}

//在pos结点后面插入
void SListInsertAfter(SListNode *pos, SLDataType data)
{
	 assert(pos != NULL);
	 /*SListNode *node = (SListNode*)malloc(sizeof(SListNode));
	 node->data = data;*/
	 SListNode *node = BuySListNode(data);
	 node->next = pos->next;
	 pos->next = node;
}

//删除pos结点后边的结点
void SListEraseAfter(SListNode *pos)
{
	 assert(pos != NULL);
	 SListNode *next = pos->next->next;
	 free(pos->next);
	 pos->next = next;
}

//删除第一个遇到的data结点
void SListRemove(SList *list, SLDataType data)
{
	 assert(list != NULL);
	 assert(list->first != NULL);
	 SListNode *cur = list->first;
	 SListNode *prev = NULL;
	 while (cur != NULL && cur->data != data){
		  prev = cur;
		  cur = cur->next;
	 }
	 if (cur == NULL){
	 	 return;
	 } 
	 //如果prev为空就头删即可
	 if (prev == NULL){
		  SListPopFront(list);
		  return;//删完一定要记得返回,不然就执行到下面去了
	 }
	 prev->next = cur->next;
	 free(cur);
}

//打印
void SListPrint(SList *list)
{
	 for (SListNode *cur = list->first; cur != NULL; cur = cur->next)
	 {
	 	 printf("%d-->", cur->data);
	 }
	 printf("NULL\n");
}

测试部分test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"
#include<stdio.h>
#include<stdlib.h>
void Test1()
{
	 SList list;
	 SListInit(&list);
	
	 SListPushFront(&list, 4);
	 SListPushFront(&list, 3);
	 SListPushFront(&list, 2);
	 SListPushFront(&list, 1);
	 SListPrint(&list);
	
	 SListPopFront(&list);
	 SListPopFront(&list);
	 SListPrint(&list);
	
	 SListPushBack(&list, 5);
	 SListPushBack(&list, 6);
	 SListPushBack(&list, 7);
	 SListPushBack(&list, 8);
	 SListPrint(&list);
	
	 SListPopBack(&list);
	 SListPopBack(&list);
	 SListPrint(&list);
}

void Test2()
{
	 SList list;
	 SListInit(&list);
	
	 SListPushFront(&list, 4);
	 SListPushFront(&list, 3);
	 SListPushFront(&list, 2);
	 SListPushFront(&list, 1);
	 SListPrint(&list);
	 //printf("%p\n",SListFind(&list,8));
	
	 SListNode *n1 = SListFind(&list, 3);
	 //SListInsertAfter(n1, 9);
	 SListEraseAfter(n1);
	 SListPrint(&list);
}

void Test3()
{
	 SList list;
	 SListInit(&list);
	 SListPushFront(&list, 4);
	 SListPushFront(&list, 3);
	 SListPushFront(&list, 2);
	 SListPushFront(&list, 1);
	 SListPrint(&list);
	
	 SListRemove(&list, 3);
	 SListRemove(&list, 1);
	 SListPrint(&list);
}

void main()
{
	 //Test1();
	 //Test2();
	 Test3();
	 system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值