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

数据结构之线性表

目录

1 简介

2 线性表的基本概念

3 顺序存储的线性表 

3.1 定义线性表结构

3.2 初始化线性表

3.3 插入元素

3.4 删除元素

3.5 查找元素

3.6 扩容操作

3.7 打印线性表

4 线性表的应用

5 总结 


1 简介

        线性表是数据结构中最基础且常用的一种结构,它是由一组具有相同类型的元素组成的有序序列。线性表可以通过顺序存储或链式存储来实现。本文将重点介绍顺序存储的线性表,并通过C语言代码来展示其基本操作。

2 线性表的基本概念

线性表是一种线性结构,元素之间存在一对一的关系。线性表的基本操作包括:

3 顺序存储的线性表 

        顺序存储的线性表是通过数组来实现的。数组中的元素在内存中是连续存储的,因此可以通过下标直接访问元素,具有较高的访问效率。然而,顺序存储的线性表在插入和删除操作时,需要移动大量元素,时间复杂度较高。

3.1 定义线性表结构

我们首先定义一个线性表的结构体,包含以下成员:

  • data:指向存储元素的数组。

  • size:当前线性表的大小(即元素个数)。

  • capacity:线性表的最大容量。

typedef struct
{
    int *data;      // 存储元素的数组
    int size;       // 当前大小
    int capacity;   // 最大容量
} List;

3.2 初始化线性表

在初始化线性表时,我们需要为其分配一块连续的内存空间,并设置初始容量和大小。

void init(List *l)
{
    l->capacity = MAX;  // 初始容量
    l->size = 0;        // 初始大小为0
    l->data = malloc(sizeof(int) * l->capacity);  // 分配内存
}

3.3 插入元素

插入元素时,需要考虑线性表是否已满。如果已满,则需要先进行扩容操作。插入元素的时间复杂度为O(n),因为可能需要移动大量元素。

void insert(List *l, int index, int e)
{
    // 扩容
    if (l->size == l->capacity)
    {
        incr(l);
    }
    if (index == l->size)
        add(l, e);
    if (index < l->size)
    {
        for (int i = l->size - 1; i >= index; i--)
        {
            l->data[i + 1] = l->data[i];
        }
        l->data[index] = e;
        l->size++;
    }
}

3.4 删除元素

删除元素时,同样需要移动元素以填补删除后的空缺。删除操作的时间复杂度也是O(n)。

int del(List *l, int index)
{
    for (int i = index; i < l->size; i++)
    {
        l->data[i] = l->data[i + 1];
    }
    l->size--;
}

3.5 查找元素

查找操作可以通过遍历数组来实现。如果找到目标元素,则返回其索引;否则返回-1。查找操作的时间复杂度为O(n)。

int find(List *l, int val)
{
    int index = -1;
    for (int i = 0; i < l->size; i++)
    {
        if (l->data[i] == val)
        {
            index = i;
            break;
        }
    }
    return index;
}

3.6 扩容操作

当线性表的容量不足时,我们需要对其进行扩容。常见的扩容策略有:

  • 倍增:每次扩容时将容量翻倍。

  • 固定增量:每次扩容时增加固定的容量。

在本文中,我们采用倍增策略进行扩容。

void incr(List *l)
{
    if (l->size < l->capacity) return;
    int incr = l->capacity << 1;  // 容量翻倍
    l->capacity += incr;
    l->data = realloc(l->data, sizeof(int) * l->capacity);  // 重新分配内存
}

3.7 打印线性表

为了方便调试和查看线性表的状态,我们可以实现一个打印函数,输出线性表中的所有元素及其容量和大小。

int show(List *l)
{
    printf("--------------------\n");
    printf("数据:");
    for (int i = 0; i < l->size; i++)
    {
        printf("%d,", l->data[i]);
    }
    printf("\n容量:%d,大小:%d\n", l->capacity, l->size);
}

4 线性表的应用

顺序存储的线性表在实际应用中有广泛的用途,例如:

  • 数组:数组本身就是一种顺序存储的线性表。

  • 栈和队列:栈和队列可以通过顺序存储的线性表来实现。

  • 动态数组:通过动态扩容,顺序存储的线性表可以实现动态数组的功能。

5 总结 

顺序存储的线性表是一种简单且高效的数据结构,适用于元素数量相对固定且需要频繁访问的场景。然而,由于其插入和删除操作的时间复杂度较高,因此在需要频繁插入和删除的场景下,链式存储的线性表可能更为合适。

通过本文的代码示例,我们可以清晰地看到顺序存储线性表的基本操作及其实现细节。希望本文能帮助你更好地理解线性表的概念及其应用。

相关文章:

  • Django-ORM-prefetch_related
  • 排序 --- 快速排序
  • 网络配置与pip工具安装
  • 文件上传漏洞 upload-labs靶场
  • 开源数字人模型Heygem
  • 【学习笔记】《逆向工程核心原理》02.小段标记法、IA-32寄存器、栈、abex‘crackme、栈帧
  • 说一下spring的事务隔离级别?
  • 爱可以传递,幸福可以具象化
  • 基于SpringBoot的“体育购物商城”的设计与实现(源码+数据库+文档+PPT)
  • 从零开始 | C语言基础刷题DAY1
  • C++跨平台开发环境搭建全指南:工具链选型与性能优化实战
  • 信息安全风险管理简述(下):如何进行风险评估
  • 解决 GitHub Pull Request 中 DCO 问题(缺少Signed-off-by行的问题)
  • shell脚本基础
  • 防抖和节流
  • (二)seacmsv9注入管理员账号密码+orderby+limit
  • 炫云云渲染以技术赋能影视视效,打造视觉盛宴!
  • Go_zero学习笔记
  • Movavi Photo Editor深度解析:图片分辨率提升与老照片修复神器
  • React 如何实现组件懒加载以及懒加载的底层机制
  • 2025财政观察|长三角“三公”经费普降,钱要用在刀刃上
  • 沧州制造展现硬核实力:管道装备支撑大国基建,核电锚栓实现国产
  • 首个偏头痛急性治疗药物可缓解前期症状
  • “75万买299元路由器”事件进展:重庆市纪委等三部门联合介入调查
  • 联合国秘书长欢迎中美经贸高层会谈成果
  • 云南大理铁路枢纽工程建设取得两大进展,预计明年建成