单链表的实现

简介: 单链表的实现

单链表的定义


       由于顺序表的插入删除操作需要移动大量的元素,影响了运行效率,因此引入了线性表的链式存储——单链表。单链表通过一组任意的存储单元来存储线性表中的数据元素,因此它不要求在逻辑上相邻的两个元素在物理位置上也相邻。


单链表的实现

初始化

我们要先定义一个单链表的结构体,单链表需要一个链表的指针,链表中数据的个数,链表的空间大小,

typedef int SQDatatype;
typedef struct SeqList
{
  SQDatatype* ps;
  int size;
  int capacity;
}SL;


初始化链表时链表指针指向空,链表内元素个数为0,链表空间为0;


//初始化
void SLInit(SL* s1)
{
  assert(s1);
  s1->ps = NULL;
  s1->size = 0;//链表内数据个数
  s1->capacity = 0;//链表空间
}


检查扩容


       每次插入数据时我们都要检查一下链表的空间是否足够,因此可以专门下一个检查扩容的函数;

void SLCheckCapacity(SL* s1)
{
  assert(s1);
  //链表内个数和链表空间相等时需要扩容
  if (s1->size == s1->capacity)
  {
    int newcapacity = s1->capacity == 0 ? 4 : s1->capacity * 2;
    SQDatatype* tem = (SQDatatype*)realloc(s1->ps, newcapacity * sizeof(SQDatatype));
    if (tem == NULL)
    {
      perror("realloc fail");
      return;
    }
    s1->ps = tem;
    s1->capacity = newcapacity;
  }
}


       注意扩容时要用realloc而不是malloc,malloc是重新开辟空间,会覆盖之前的数据,(因为我之前写的时候,就写错成了malloc,检查了老半天);


头插


//头插
void SLPushFront(SL* s1, SQDatatype x)
{
  assert(s1);
  SLCheckCapacity(s1);
  for (int i = s1->size; i > 0; i--)
  {
    s1->ps[i] = s1->ps[i - 1];
  }
  s1->ps[0] = x;
  s1->size++;
}

  头插时把原来的元素一个个往后移,然后头插入新的元素,记得s1->size++ ,注意细节;

尾插


//尾插
void SLPushBack(SL* s1, SQDatatype x)
{
  assert(s1);
  SLCheckCapacity(s1);
  s1->ps[s1->size] = x;
  s1->size++;
}


头删

       删除数据时链表不能为空;

//头删
void SLPopFront(SL* s1)
{
  assert(s1);
  assert(s1->size != 0);
  for (int i = 0; i < s1->size - 1; i++)
  {
    s1->ps[i] = s1->ps[i + 1];
  }
  s1->size--;
}

尾删

       删除数据时链表不能为空;

//尾删
void SLPopBack(SL* s1)
{
  assert(s1);
  assert(s1->size != 0);
  s1->size--;
}

指定位置插入

       注意判断pos的值,如果pos不在0到size中,会直接报错,所以要加个断言

//指定位置插入
void SLInsert(SL* s1, int pos, SQDatatype x)
{
  assert(s1);
  assert(pos >= 0 && pos <= s1->size);
  SLCheckCapacity(s1);
  for (int i = s1->size; i > pos; i--)
  {
    s1->ps[i] = s1->ps[i - 1];
  }
  s1->ps[pos] = x;
  s1->size++;
 
}


指定位置删除

       注意判断pos的值,如果pos不在0到size中,会直接报错,所以要加个断言

//指定位置删除
void SLErase(SL* s1, int pos)
{
  assert(s1);
  assert(pos >= 0 && pos <= s1->size);
  for (int i = pos; i < s1->size - 1; i++)
  {
    s1->ps[i] = s1->ps[i + 1];
  }
  s1->size--;
}

总结(废话)


       单链表是动态的顺序表,对于初学者可以锻炼自己的代码能力,当你熟悉之后就会发现很简单,难点就是初学时不清楚细节,还是要多多练习;

       一起加油!

完整代码

#pragma once
 
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
 
typedef int SQDatatype;
typedef struct SeqList
{
  SQDatatype* ps;
  int size;
  int capacity;
}SL;
//初始化
void SLInit(SL* s1);
//检查扩容
void SLCheckCapacity(SL* s1);
//头插
void SLPushFront(SL* s1, SQDatatype x);
//尾插
void SLPushBack(SL* s1, SQDatatype x);
//头删
void SLPopFront(SL* s1);
//尾删
void SLPopBack(SL* s1);
//指定位置插入
void SLInsert(SL* s1, int pos, SQDatatype x);
//指定位置删除
void SLErase(SL* s1, int pos);
//查找数据
void SLFind(SL* s1, SQDatatype x);
//修改数据
void SLModity(SL* s1, int pos, SQDatatype x);
//打印链表
void SLPrintf(SL* s1);
//销毁链表
void SLDestroy(SL* s1);


#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
 
void SLInit(SL* s1)
{
  assert(s1);
  s1->ps = NULL;
  s1->size = 0;//链表内数据个数
  s1->capacity = 0;//链表空间
}
 
void SLCheckCapacity(SL* s1)
{
  assert(s1);
  //链表内个数和链表空间相等时需要扩容
  if (s1->size == s1->capacity)
  {
    int newcapacity = s1->capacity == 0 ? 4 : s1->capacity * 2;
    SQDatatype* tem = (SQDatatype*)realloc(s1->ps, newcapacity * sizeof(SQDatatype));
    if (tem == NULL)
    {
      perror("realloc fail");
      return;
    }
    s1->ps = tem;
    s1->capacity = newcapacity;
  }
}
//头插
void SLPushFront(SL* s1, SQDatatype x)
{
  assert(s1);
  SLCheckCapacity(s1);
  for (int i = s1->size; i > 0; i--)
  {
    s1->ps[i] = s1->ps[i - 1];
  }
  s1->ps[0] = x;
  s1->size++;
}
//尾插
void SLPushBack(SL* s1, SQDatatype x)
{
  assert(s1);
  SLCheckCapacity(s1);
  s1->ps[s1->size] = x;
  s1->size++;
}
 
//头删
void SLPopFront(SL* s1)
{
  assert(s1);
  assert(s1->size != 0);
  for (int i = 0; i < s1->size - 1; i++)
  {
    s1->ps[i] = s1->ps[i + 1];
  }
  s1->size--;
}
//尾删
void SLPopBack(SL* s1)
{
  assert(s1);
  assert(s1->size != 0);
  s1->size--;
}
//指定位置插入
void SLInsert(SL* s1, int pos, SQDatatype x)
{
  assert(s1);
  assert(pos >= 0 && pos <= s1->size);
  SLCheckCapacity(s1);
  for (int i = s1->size; i > pos; i--)
  {
    s1->ps[i] = s1->ps[i - 1];
  }
  s1->ps[pos] = x;
  s1->size++;
 
}
//指定位置删除
void SLErase(SL* s1, int pos)
{
  assert(s1);
  assert(pos >= 0 && pos <= s1->size);
  for (int i = pos; i < s1->size - 1; i++)
  {
    s1->ps[i] = s1->ps[i + 1];
  }
  s1->size--;
}
//查找数据
void SLFind(SL* s1, SQDatatype x)
{
  assert(s1);
  int flag = 0;
  for (int i = 0; i < s1->size; i++)
  {
    if (s1->ps[i] == x)
    {
      flag = 1;
      printf("找到了,在下表为%d的位置\n", i);
 
    }
  }
  if(flag==0)
  printf("该数据不存在\n");
}
 
//修改数据
void SLModity(SL* s1, int pos, SQDatatype x)
{
  assert(s1);
  assert(pos >= 0 && pos <= s1->size);
  s1->ps[pos] = x;
}
//打印链表
void SLPrintf(SL* s1)
{
  assert(s1);
  for (int i = 0; i < s1->size; i++)
  {
    printf("%d ", s1->ps[i]);
  }
  printf("\n");
}
//销毁链表
void SLDestroy(SL* s1)
{
  assert(s1);
  free(s1->ps);
  SLInit(s1);
}
 
#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
int main()
{
  SL s1;
  SLInit(&s1);
  SLPushFront(&s1, 1);
  SLPushFront(&s1, 2);
  SLPushFront(&s1, 3);
  SLPushFront(&s1, 4);
  SLPushFront(&s1, 5);
  SLPushBack(&s1, 100);
  SLPushBack(&s1, 200);
  SLPushBack(&s1, 300);
  SLPushBack(&s1, 400);
  SLPushBack(&s1, 500);
  /*SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);
  SLPopBack(&s1);*/
  /*SLErase(&s1, 2);*/
  SLModity(&s1, 3, 5000);
  SLFind(&s1, 5000);
  SLPrintf(&s1);
  SLDestroy(&s1);
  return 0;
}


相关文章
|
3天前
|
人工智能 自然语言处理 安全
阿里云AI数智鉴密:AI 生成内容如何拿到一张"防篡改的身份证"
隐形水印 + C2PA签名:让AI生成内容“持证上岗”。
1111 0
|
12天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
3708 4
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
24天前
|
人工智能 缓存 前端开发
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
DeepSeek Harness + DeepSeek V4 Pro 项目实战保姆级教程!手把手带你从零安装开源 AI 编程工具,开发架构图、知识讲解网站、3D 网页游戏、全栈 AI 应用 4 个项目,覆盖运行模式选择、插件安装与开发,看看能不能对标 Claude。
13511 93
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
|
17天前
|
Web App开发 人工智能 API
16 个超火的 DeepSeek Harness 插件,大肥鱼已经落后 N 个版本了。。。
DeepSeek Harness 精选插件推荐合集,从图片识别、浏览器操控、多 Agent 协作到手机远程控制,一口气带你看完 DSH 社区热门的十几个插件,覆盖技能扩展、UI 界面增强、整活玩法三大类,让你的鲸鱼变得更强。
1974 5
|
3天前
|
人工智能 运维 BI
阿里云千问办公QwenWork深度解析:基于Qwen3.8,六大核心能力重构企业全自动化工作流与计费选型指南
传统AI办公工具大多停留在对话问答、文档摘要、简单文案生成层面,只能完成单点碎片化任务,无法自主拆解复杂业务流程,很难串联多工具、多文档、外部业务系统完成端到端完整工作交付。很多企业在落地AI办公的时候,需要组合多款不同工具,来回切换界面,手动复制粘贴中间结果,智能化改造落地门槛居高不下。千问办公QwenWork是整合多款智能体产品能力打造的一体化企业办公智能体平台,底层基座依托Qwen3.8大模型,打通桌面端Agent、云端Agent、企业协同Agent三种运行形态,不再局限简单问答,接收业务目标之后自主拆解任务步骤,调用各类工具,处理文档、表格、浏览器自动化、数据查询,直接输出可交付的办公
1027 0
|
13天前
|
人工智能 Linux iOS开发
Ollama使用教程:Ollama官网下载、Ollama本地部署大模型(2026最新)
Ollama 是一款免费开源的本地大模型运行工具,支持在 Windows/macOS/Linux 上离线运行 Qwen、DeepSeek、Llama 等主流开源模型,数据不出本机、隐私安全。提供 OpenAI 兼容 API,命令行一键拉取/运行/管理模型,无需联网,无调用限制,是开发者与 AI 爱好者部署本地 AI 助手的理想选择。(239 字)
|
9天前
|
人工智能 并行计算 数据可视化
秋叶ComfyUI-AKI最新整合包|完整部署教程+核心指令手册
秋叶ComfyUI-AKI一键整合包,国内适配最优、稳定性最强的商用/学习级版本:全封装虚拟环境、预装90%常用节点、内置绘世启动器与成熟工作流,免配置、零依赖、解压即用,完美兼顾新手入门与专业批量生产需求。(239字)
|
10天前
|
人工智能 监控 测试技术
Qwen3.8-Flash 来了,100万上下文、Agent、Coding 都加强了
8月26日,通义千问发布Qwen3.8-Flash-Next:125B参数、每Token仅激活6B,原生支持26万Token、可扩展至100万上下文;Coding、Agent与工具调用能力显著增强,面向真实软件工程任务,推动大模型从“回答问题”迈向“完成工作”。

热门文章

最新文章