单链表的基本操作(一(无头单向非循环链表增删查改实现)

本文介绍了一种无头单向非循环链表的基本操作实现方法,包括节点的创建、初始化、销毁、插入、删除等功能,并通过具体代码示例展示了如何进行链表的管理。

单链表的基本操作(无头单向非循环链表增删查改实现)
SeqList.h文件:

#ifndef _SLIST_H_
#define _SLIST_H_
#include<stdio.h>
#include<Windows.h>
typedef int SLTDataType;
typedef struct SListNode
{
 SLTDataType data;
 struct SListNode* next;
}SListNode;
void SListInit(SListNode **pphead);//初始化
SListNode *BuySListNode(SLTDataType x);//申请一个新节点
void SListDestory(SListNode **pphead);//摧毁
void SListPushFront(SListNode **pphead, SLTDataType x);//前插
void SListPopFront(SListNode **pphead);//前删
SListNode *SListFind(SListNode *pphead,SLTDataType x);//找值为x的节点
void SListInsertAfter(SListNode *pos, SLTDataType x);//在pos的后面插入值为x的节点
void SListEraseAfter(SListNode *pos);//后删
void SListRemove(SListNode **pphead, SLTDataType x);//删掉
void SListRemoveAll(SListNode **pphead, SLTDataType x);//删掉所有
void SListPrint(SListNode *phead);//打印
#endif

SeqList.c文件:

#include "SList.h"

SListNode *BuySListNode(SLTDataType x)//申请一个值为x的新节点
{
 SListNode *res =(SListNode*) malloc(sizeof(SListNode));
 res->data = x;
 res->next = NULL;
 return res;
}

void SListInit(SListNode **pphead)//初始化
{
 *pphead = NULL;
}

void SListDestory(SListNode **pphead)//摧毁
{
 if (*pphead == NULL)//判断头节点是否为空
 {
  return;
 }
 while ((*pphead)->next)//依次删除头节点的下一个节点
 {
  SListEraseAfter(*pphead);
 }
 free(*pphead);//释放头节点
 *pphead = NULL;//头节点值为NULL
}

void SListPushFront(SListNode **pphead,SLTDataType x)//前插
{
 SListNode *tmp = BuySListNode(x);
 tmp->next = *pphead;
 *pphead = tmp;
}

void SListPopFront(SListNode **pphead)//前删
{
 if (*pphead == NULL)
 {
  return;
 }
 SListNode *tmp = (*pphead)->next;
 free(*pphead);
 *pphead = tmp;
}


SListNode *SListFind(SListNode *pphead, SLTDataType x)//查找
{
 SListNode *tmp ;
 for (tmp = pphead; tmp; tmp->next)
 {
  if (tmp->data == x)
  {
   return tmp;
  }
 }
 return NULL;
}


void SListInsertAfter(SListNode *pos, SLTDataType x)//在pos的后面插入
{
 SListNode *tmp = BuySListNode(x);
 tmp->next = pos->next;
 pos->next = tmp;
}

void SListEraseAfter(SListNode *pos)//后删
{
 SListNode*tmp = pos->next;
 if (tmp == NULL)
 {
  return;
 }
 pos->next = tmp->next;
 free(tmp);
}

void SListRemove(SListNode **pphead, SLTDataType x)//删掉第一个值为x的节点
{
 if (*pphead == NULL)
 {
  return;
 }
 SListNode *tmp = *pphead;
 if ((*pphead)->data == x)
 {
  SListEraseAfter(pphead);
  return;
 }
 for (tmp = *pphead; tmp->next; tmp = tmp->next)
 {
  if (tmp->next->data == x)
  {
   SListEraseAfter(tmp);
   return;
  }
 }
}

void SListRemoveAll(SListNode **pphead, SLTDataType x)//删掉所有值为x的节点
{
 SListNode *tmp;
 if (*pphead && (*pphead)->data == x)
 {
  SListPopFront(pphead);
 }
 for (tmp = *pphead; tmp&&tmp->next;)
 {
  if (tmp->next->data == x)
  {
   SListEraseAfter(tmp);
  }
  else
  {
   tmp = tmp->next;
  }
 }
}

void SListPrint(SListNode *phead)//打印
{
 SListNode *tmp = phead;
 for (tmp = phead; tmp; tmp = tmp->next)
 {
  printf("%d->", tmp->data);
 }
 printf("NULL\n");
}

main.c文件:

#include "SList.h"
int main()
{
 SListNode *phead;
 SListInit(&phead);
 SListPushFront(&phead, 4);
 SListPushFront(&phead, 5);
 SListPushFront(&phead, 4);
 SListPushFront(&phead, 4);
 SListPushFront(&phead, 6);
 SListPushFront(&phead, 4);
 //SListPopFront(&phead);
 //SListRemove(&phead, 6);
 SListRemoveAll(&phead, 10);
 SListPrint(phead);
 SListDestory(&phead);
 system("pause");
 return 0;
}
单链表种常见的数据结构,以下从定义、实现操作方法、优缺点、应用场景等方面进行详细介绍: ### 定义 单链表的基本结构包含个数据域和个指针域,指针域用于查找位置,数据域用于存储数据。例如在存储学生的姓名和年龄时,可在结构体中添加相应的数据;若使用 C++,还能用 string 类型存储姓名 [^4]。 ### 实现 在代码实现中,通常会定义个结构体来表示单链表的节点。以下是使用 C 语言实现单链表节点的示例: ```c typedef int SLTDateType; typedef struct SListNode { SLTDateType data; struct SListNode* next; } SLTNode; ``` ### 操作方法 单链表的基本功能围绕数据的增删查改展开,以下是些常见操作的接口定义: ```c // 创建个结点 SLTNode* BuyListNode(SLTDateType x); // 销毁单链表 void SLTDestory(SLTNode** pphead); // 单链表头插 void SLTPushFront(SLTNode** pphead, SLTDateType x); // 单链表尾插 void SLTPushBack(SLTNode** pphead, SLTDateType x); // 单链表头删 void SLTPopFront(SLTNode** pphead); // 单链表尾删 void SLTPopBack(SLTNode** pphead); // 单链表结点查找 SLTNode* SLTNodeFind(SLTNode* phead, SLTDateType x); // 单链表结点删除(删除 pos 位置的结点) void SLTErase(SLTNode** pphead, SLTNode* pos); // 单链表结点删除(删除 pos 位置之后的结点) void SLTEraseAfter(SLTNode** pphead, SLTNode* pos); // 单链表结点插入(在 pos 之前插入) void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDateType x); // 单链表结点插入(在 pos 之后插入) void SLTInsertBack(SLTNode** pphead, SLTNode* pos, SLTDateType x); // 单链表结点修改 void SLTModify(SLTNode* phead, SLTNode* pos, SLTDateType x); // 打印单链表 void SLTPrint(SLTNode* phead); ``` ### 优缺点 单链表存在些缺陷,在实际学习工作中并非特别实用,但掌握单链表是学习复杂数据结构的必要基础 [^1]。无头单向非循环链表结构简单,般不单独用于存储数据,更多作为其他数据结构的子结构,如哈希桶、图的邻接表等,且在笔试面试中经常出现;带头双向循环链表结构最复杂,常用于单独存储数据,实际使用的链表数据结构多为此类型,虽然结构复杂,但实现后会带来很多优势,代码实现反而简单 [^3]。 ### 应用场景 无头单向非循环链表常作为其他数据结构的子结构,如哈希桶、图的邻接表等;带头双向循环链表则用于单独存储数据 [^3]。 ### 销毁操作 单链表的销毁需要传址调用,遍历链表并逐步释放每个节点的内存,因为链表的每个节点都是单独的内存空间,释放过程相对复杂,与顺序表只需释放次不同 [^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值