当前位置: 首页 > news >正文

数据结构1-概要、单向链表

摘要:介绍了数据结构中的链表实现。首先概述数据结构的基本概念,包括时间复杂度、空间复杂度等核心指标,以及数据结构的主要分类。重点讲解了链表的特点、分类及实现方法,详细剖析了单向链表的节点定义、创建、头插法、遍历和删除等关键操作,并提供了完整的C语言代码实现。文章还通过对比顺序链表与链表的优缺点,突出链表在动态内存管理方面的优势。最后给出链表操作的实践练习建议,包括多文件编程的实现方法。

一、概要

1、概念

        数据结构是计算机存储、组织和管理数据的方式,旨在实现高效的数据访问和修改。它关注数据元素之间的逻辑关系、物理存储方式以及相关操作(如插入、删除、查找等)

        程序 = 数据结构 + 算法

2、衡量代码的质量和效率

(1)时间复杂度:数据量的增长与程序运行时间的增长所呈现的比例函数关系,称为时间渐进复杂度函数,也简称时间复杂度。

  • 常见的时间复杂度(低 -> 高):
    • O(1):程序的运行时间与输入数据量无关,始终保持恒定
    • O(logn):程序的运行时间随输入数据量的增长而增长,但增长速度逐渐减慢,最终趋于恒定
    • O(n):程序的运行时间与输入数据量成正比
    • O(nlogn):程序的运行时间是线性时间和对数时间的乘积
    • O(n^2):程序的运行时间与输入数据量的平方成正比
    • O(n^3):程序的运行时间与输入数据量的立方成正比

(2)空间复杂度:数据的增长与程序占据空间的增长所呈现的比例函数关系,称为空间复杂度。

3、数据结构分类

(1)逻辑结构:

        线性结构(表)、非线性结构(树)(图)

(2)存储结构:

        顺序存储、链式存储、散列存储、索引存储

(3)常见的数据结构:

        顺序表、链式表、顺序栈、链式栈、顺序队列、链式队列、二叉树、邻接表、邻接矩阵

二、链表

1、链表概念

(1)顺序链表(数组)特点:

  • 存储空间连续
  • 访问元素方便
  • 无法利用小的空间,必须连续的大空间
  • 顺序表元素必须为有限的(不存在无限连续的空间)
    插入和删除效率低

(2)链表特点:

  • 存储空间不需要连续
  • 可以利用一些小的存储空间
  • 访问元素不方便
  • 链表元素可以没有上限
  • 插入和删除效率高

2、链表分类

(1)单向链表:只能通过链表节点找到后一个节点,访问链表元素的方向是单向的

A → B → C → NULL

(2)双向链表:能够通过链表节点找到前一个节点和后一个节点

NULL ⇄ A ⇄ B ⇄ C ⇄ NULL

(3)循环列表:能够通过第一节点快速找到最后一个节点,能够通过最后一个节点快速找到第一个节

 A → B → C → A (循环)

(4)内核链表:Linux内核所采用的一种通用的链表结构

三、单向链表

1、定义链表节点类型

(1)链表存放数据的类型

typedef int datatype;                

  • 定义了datatypeint类型,表明链表中存放的数据类型为整数

(2)链表节点类型

typedef struct node {
datatype data;                        
//存放数据空间
        struct node *pnext;                 //存放下一个节点地址
}linknode;

  • 定义了一个名为node的结构体,用来表示链表中的节点。结构体中有两个成员:
  • data:用来存放数据,其类型为datatype
  • pnext:是一个指向node结构体的指针,用来存放下一个节点的地址。
  • 最后,node结构体被typedef定义为linknode类型,方便后续使用。

2、空链表的创建

(1)创建一个空的链表节点:

        data不需要赋值(最好赋值),空白节点不存放数据,主要为了保证链表操作的便利性,pnext必须赋值为NULL,表示该节点为最后一个节点,将节点地址返回;

(2)代码如下:

/* 创建一个空链表 */
linknode *create_empty_linklist(void)
{
linknode *ptmpnode = NULL;
ptmpnode = malloc(sizeof(linknode));
if (NULL == ptmpnode)
{
perror("fail to malloc");
return NULL;
}
ptmpnode->pnext = NULL;

        return ptmpnode;

}

3、链表的头插法:

(1)步骤:

  1. 申请新的节点空间
  2. 将存放的数据让入新申请的数据空间中
  3. 将新申请节点的pnext赋值为空白节点的pnext
  4. 将空白节点pnext赋值为新申请节点

(2)代码实现:

/* 插入一个节点 */
int insert_head_linklist(linknode *phead, datatype tmpdata)
{
linknode *ptmpnode = NULL;
ptmpnode = malloc(sizeof(linknode));           
//申请空间
        if (NULL == ptmpnode)
{
perror("fail to malloc");
return -1;
}
ptmpnode->data = tmpdata;                       
  //存放数据

        ptmpnode->pnext = phead->pnext;             //存放下一个节点地址

        phead->pnext = ptmpnode;                          //更新空白的节点的pnext


        return 0;
}

4、链表元素遍历

(1)访问链表中每个节点元素

(2)两种方法:

/* 第一种方法 遍历*/

while (p != NULL)     // 指针p当前指向的是链表中的第一个节点

{

        p = p -> pnext;

}

/* 第二种方法 遍历*/

while (p ->pnext != NULL)

{

        p = p -> pnext;

}

- 方法一:多用于遍历链表中所有节点元素

- 方法二:多用于找到链表最后一个节点

(3)代码实现:

void show_linklist(linknode *phead)
{
linknode *ptmpnode = NULL;
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
printf("%d ", ptmpnode->data);
ptmpnode = ptmpnode->pnext;
}
printf("\n");


        return;
}

5、链表元素删除

(1)步骤:

  1. 定义两个指针ptmpnode用来遍历链表查找要删除的节点元素,pprenode永远只想ptmpnode的前一个节点
  2. 当ptmpnode找到要删除的节点元素,让pprenode->pnext赋值为ptmpnode->pnext将要删除的节点元素释放
  3. 让ptmpnode判断下一个节点元素是否要删除,直到该指针指向NULL为止

(2)代码实现:

int delete_linklist(linknode *phead, datatype tmpdata)
{
linknode *pprenode = NULL;
linknode *ptmpnode = NULL;
pprenode = phead;
ptmpnode = phead->pnext;
while (ptmpnode != NULL)
{
if (ptmpnode->data == tmpdata)
{
pprenode->pnext = ptmpnode->pnext;
free(ptmpnode);
ptmpnode = pprenode->pnext;
}
else
{
ptmpnode = ptmpnode->pnext;
pprenode = pprenode->pnext;
}
}
return 0;
}

四、练习

1、便于数据结构的练习,将虚拟机进行联网操作,安装visual studio code,同时配置语言实现多文件操作,便于我们进行代码的编写和操作。

2、练习:实现链表的创建,利用链表头插法进行链表元素的遍历和链表元素的删除

(1)main函数,定义链表,函数的调用

(2)各个参量的声明

(3)函数实现的具体过程

(4)结果的实现

http://www.dtcms.com/a/311912.html

相关文章:

  • JVM中的垃圾回收暂停是什么,为什么会出现暂停,不同的垃圾回收机制暂停对比
  • 知识随记-----用 Qt 打造优雅的密码输入框:添加右侧眼睛图标切换显示
  • Ubuntu系统间SSH控制详细指南
  • 由浅入深使用LangGraph创建一个Agent工作流
  • 零拷贝技术:高效数据传输的核心原理与应用
  • 用 JavaSwing 开发经典横版射击游戏:从 0 到 1 实现简易 Contra-like 游戏
  • 20250801-2-Kubernetes 存储-节点本地数据卷_笔记
  • IMAP电子邮件归档系统Mail-Archiver
  • UE5 Insight ProfileCPU
  • 自动驾驶嵌入式软件工程师面试题【持续更新】
  • 回归预测 | Matlab实现CNN-LSTM-self-Attention多变量回归预测
  • Java中的字符串 - String 类
  • 编程与数学 03-002 计算机网络 19_网络新技术研究
  • Java试题-选择题(6)
  • 苏州银行招苏新基金研究部研究员
  • python匿名函数lambda
  • Windows Server软件限制策略(SRP)配置
  • linux进度条程序
  • Educational Codeforces Round 181 (Rated for Div. 2) A-C
  • Mujoco(MuJoCo,全称Multi - Joint dynamics with Contact)一种高性能的物理引擎
  • LLM微调笔记
  • 泛型(java!java!java!)
  • 大模型大厂面试题及解析
  • 【MATLAB】(四)函数运算
  • “AI+固态”从蓝海愿景变为刚性需求,消费电池老将转身狂奔
  • MySQL中索引失效的常见场景
  • 人工智能之数学基础:离散型随机事件概率(古典概型)
  • 基于 LightGBM 的二手车价格预测
  • TCL --- 列表_part2
  • AAAI赶稿后的心得