数据结构 - 线性表(顺序表)

news2024/12/25 12:53:22

线性表是什么

线性表是包含若干数据元素的一个线性序列,记为: L = (a0,…ai-1,ai,ai+1,…an-1)

  • L为表名,ai(0≤ i ≤n-1)为数据元素;
  • n为表长,n>0时,线性表 L 为非空表,否则为空表。

线性表L可用二元组形式描述(程序员间的表述):
L = (D,R)
即线性表 L 包含数据元素集合 D 和关系集合 R
D = {ai | ai ∈ datatype ,i=0,1,2, …n-1 ,n≥0}
R = {<ai, ai+1> | ai,ai+1∈D,0 ≤ i ≤ n-2}

  • 关系符<ai,ai+1>在这里称为有序对
  • 表示任意相邻的两个元素之间的一种先后关系
  • ai 是 ai+1直接前驱,ai+1 是 ai直接后继

在这里插入图片描述

线性表的特征

  • 对非空表,a0是表头,无前驱;
  • an-1是表尾,无后继;
  • 其它的每个元素 ai 有且仅有一个直接前驱 ai-1 和 一个直接后继 ai+1

线性表 - 顺序表

顺序存储结构的表示1

若将线性表 L = (a0,a1,…,an-1) 中的各元素依次存储于计算机一片连续的存储空间。

设 Loc(ai) 为 ai 的地址,Loc(a0) = b,每个元素占 d 个单元, 则:Loc(ai) = b + i*d

顺序存储结构的特点

  • 逻辑上相邻的元素 ai,ai+1,其存储位置也是相邻的
  • 对数据元素 ai 的存取为随机存取按地址存取
  • 存储密度高
    • 存储密度 D = (数据结构中元素所占存储空间)/ (整个数据结构所占空间)
  • 不足:对表的插入和删除等运算的时间复杂度较差

顺序存储结构的表示2

在 C 语言中,可借助于一维数组类型来描述线性表的顺序存储结构:

#define N 100
typedef int data_t;
typedef struct
{
	data_t data[N]; //表的存储空间;
	int last;
} sqlist, *sqlink;
	

在这里插入图片描述
上面的代码可以这么理解:

  • typedef struct sqlist 可以看作是整个图书馆,而这里的 data[N] 是图书馆里的书,结构体里的 last 就可以看作是一共有多少本书,虽然叫作 last 是因为它是顺序表里最后一个元素的下标,但是这个下标也可以标识一共有多少本书,只要可以代表总数,也可以换成别的。
  • 那为什么要用 typedef 定义变量和结构体?因为这样可以复用代码,比如这里的 data_t 可以换成 char ,也可以换成别的类型,它可以是书,也可以是餐具等等,结构体 typedef 同理

线性表的基本运算

设线性表 L = (a0,a1,…,an-1) , 对 L 的基本运算有:
1)建立一个空表:list_create(L)
2)置空表:list_clear(L)。若成功返回1,失败返回0。
3)判断表是否为空:list_empty(L)。若表为空,返回值为 0,否则返回 -1
4)求表长:length(L)
5)取表中某个元素:GetList(L,i),即ai。要求0≤ i ≤ length(L) - 1
6)定位运算:Locate(L,x)。确定元素 x 在表 L 中的位置(或序号)
L o c a t e ( L , x ) = { i 当元素 x = a i ∈ L ,且 a i 是第一个与 x 相等时 − 1 当 x 不属于 L 时 Locate(L,x)=\left\{ \begin{array}{rcl} i & & {当元素x=a_i∈L,且a_i是第一个与x相等时}\\ -1 & & {当x不属于L时}\\ \end{array} \right. Locate(L,x)={i1当元素x=aiL,且ai是第一个与x相等时x不属于L
7)插入:Insert(L,x,i)。将元素 x 插入到表 L 中第 i 个元素 ai 之前,且表长 +1。

线性表运算的实现

我们在实现时一般会写三个文件(顺序表):
1、sqlist.h 定义数据结构,定义线性表运算
2、sqlist.c 实现线性表运算
3、 test.c 实现实际功能,调 sqlist.h 接口
这样写的好处是:①结构清晰; ②代码复用性高:自己可以反复用,不管是现在的项目,还是以后的项目都可以用;同事也可以用。③给外包公司接口,实现部分给他们二进制 .so 文件,这样以后业务升级还找你

分文件编写以后怎么编译运行呢?

  • 可以一条一条的把 .c 汇编为 .o ,最后链接 .o 和 库文件 运行:
    例如:

    gcc -c sqlist.c -o sqlist.o
    
    gcc -c test.c -o test.o
    
    gcc test.o sqlist.o -o test
    
  • 利用简洁的命令进行编译执行:

    gcc *.c -o test
    
  • 利用 Makefile 进行编译

    SRC=sqlist.c
    SRC+=test.c
    
    test:$(SRC)
      gcc $^ -o $@
    
    .PHONY:clean
    
    clean:
      rm *.o
    

sqlist.c 中线性表运算具体实现

  • 创建顺序表 list_create()

    • 思路:
      1. 分配内存空间(一定要注意检查分配成功没有)
      2. 初始化
      3. 返回顺序表指针
    • 代码:
    sqlink list_create()
    {
    	//malloc
    	sqlink L;
    	L = (sqlink)malloc(sizeof(sqlist));
    	if(L == NULL)
    	{
    		printf("list malloc failed!\n");
    		return L;
    	}
    
        //init
        memset(L, 0, sizeof(sqlist));
        L->last = -1;
    
        //return
        return L;
    }
    
  • 清空顺序表 list_clear(sqlink L)

    • 思路:
      1. 先检查表原来是否是空表(如果是空表的话清空也没啥意义)(有疑问??)
      2. 然后给表空间置0,给表尾元素挪到初始位置(-1)
    • 代码:
     int list_clear(sqlink L)
     {
         if(L == NULL)
         {
              printf("the list is null!\n");
              return -1;
         }
    
     	memset(L, 0, sizeof(sqlist));
     	L->last = -1;
    
     	return 0;
     }
    
  • 判断顺序表是否为空表 list_empty(sqlink L)

    • 思路:
      1. 判断指针 L 是否为空,避免非法操作
      2. 判断表尾元素是否还在初始位置(-1),如果在初始位置证明是空表,返回 0,如果不是的话就返回 1
    • 代码:
    int list_empty(sqlink L)
    {
    	if (L == NULL)
    	{
    		printf("illegal operation!\n");
    		return -1;
    	}
    	
    	if (L->last == -1)
    	{
    		return 0;
    	}
    	else
    	{
    		return 1;
    	}
    }
    
  • 计算顺序表长度 list_length(sqlink L)

    • 思路:
      1. 判断指针 L 是否为空,避免非法操作
      2. 顺序表长度可以看作是表尾元素下标 + 1
    • 代码:
    int list_length(sqlink L)
    {
      if (L == NULL)
      {
      	return -1;
      }
      
      return (L->last + 1);
    }
    
  • 向顺序表中插入元素

    • 思路:
      1. 判断顺序表满不满,如果已经满了就不能再插入元素了
      2. 判断元素插入位置是否合法(插入位置不能小于下标 0 ,也不能大于顺序表末尾元素下标 L->last 的后一位)
      3. 如果以上两条都通过,那么开始新增元素,新增元素按照下图的箭头所示,依次从后往前的每个元素都向后移动一位给新增元素腾地方。比如插入元素位置在下标为 1 的地方,那么就先移动下标 4 的元素 9 到下标 5 ,然后移动下标 3 的元素 4 到 下标 4,······以此类推,把下标 1 的元素移动到下标 2 后,就可以进行下一步了
      4. 把要新增的值赋给数组的新增元素
      5. 末尾元素下标加一
        在这里插入图片描述
    • 代码:
    int list_insert(sqlink L, data_t value, int pos)
    {
      int i;
      if (L->last == N - 1)
      {
      	printf("the list is full!\n");
      	return -1;
      }
      
      if (pos < 0 || pos > L->last + 1)
      {
      	printf("the insertion position is invalid\n");
      	return -1;
      }
    
      for (i = L->last; i <= pos ; i--)
      {
      	L->data[i+1] = L->data[i];
      }
      
      L->data[pos] = value;
      
      L->last++;
    
      return 0;
    }
    
  • 打印顺序表 list_show(sqlink L)

    • 思路:
      1. 判断表指针 L 是否为空,避免非法操作
      2. 判断表尾元素是否在初始位置,给予空表提示
      3. 打印顺序表
    • 代码:
    int list_show(sqlink L)
    {
      int i;
       
      if (L == NULL)
      {
      	printf("invalid!\n");
      	return -1;
      }
      
      if (L->last == -1)
      {
      	printf("the list is null!\n");
      	return 0;
      }
    
      for (i = 0; i <= L->last; i++)
      {
      	printf("%d ", L->data[i]);
      }
      
      printf("\n");
    
  • 销毁顺序表 list_free(sqlink L) ,因为有时候程序并不能主动释放顺序表内存空间,一直占用内存会造成浪费

    • 思路:
      1. 判断表指针 L 是否为空,如果为空那么这个表就没有建立起来,也没必要销毁
      2. 释放 L 内存空间
      3. 把表指针 L 置空,不再让其指向这段已经被释放的内存空间
    • 代码:
    int list_delete(sqlink L)
    {
    	if (L == NULL)
    	{
    		printf("invalid!\n");
    		return -1;
    	}
    
        free(L);
        L = NULL;
        
        return 0;
    }    
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031223.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue的详细教程--用Vue-cli搭建SPA项目

Vue的详细教程--用Vue-cli搭建SPA项目 1.Vue-cli是什么2.什么是SPA项目1.vue init webpack spa2.一问一答模式2&#xff1a;运行完上面的命令后&#xff0c;我们需要将当前路径改变到SPA这个文件夹内&#xff0c;然后安装需要的模块此步骤可理解成&#xff1a;maven的web项目创…

PY32F003F18之ADC问题

普然单片机PY32F003F18的内部有一个LDO&#xff0c;其电压固定为1.2V。我在用官方程序测试时&#xff0c;若接上USB转串口的RX导线&#xff0c;向PC发送数据&#xff0c;读内部参考电压比较正确&#xff0c;但是&#xff0c;当接上USB转串口的TX导线时&#xff0c;发现读到内部…

【从0学习Solidity】15. 异常

【从0学习Solidity】15. 异常 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈开发…

ruoyi框架开发LOT项目

背景 最近闲着就用ruoyi的框架写了一个LOT项目&#xff0c;个人觉得效果还可以。 1、首页 2、企业管理 3、用户管理 4、设备列表 5、设备列表标签展示 6、设备详情页面 7、大屏展示界面 8、结束 -----华丽的分割线&#xff0c;以下是凑字数&#xff0c;大家不用花时间看&…

2023年中国研究生数学建模竞赛D题解题思路

为了更好的帮助大家第一天选题&#xff0c;这里首先为大家带来D题解题思路&#xff0c;分析对应赛题之后做题阶段可能会遇到的各种难点。 稍后会带来D题的详细解析思路&#xff0c;以及相关的其他版本解题思路 成品论文等资料。 赛题难度评估&#xff1a;A、B>C>E、F&g…

分享demo:Vue3 使用element plus + vue-i18实现国际化

&#x1f447;面是demo展示 PS&#xff1a;点赞关注私信获取demo

任务计划不执行bat脚本排查思路

问题&#xff1a; 我有一个任务计划&#xff0c;执行的是一个bat脚本,显示也已经操作成功了&#xff0c;但是没任何变化 排查&#xff1a; 1、把cmd文件拖入到cmd中执行查看 发现执行的时候是乱码的&#xff0c;肯定就是编码问题引起&#xff0c;在cmd执行前&#xff0c;提前切…

ruoyi-nbcio项目增加右上角的消息提醒

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 因为以后流程的通知需要提醒&#xff0c;所以右上角需要增加消息提醒。 1、增加右上角的按钮与信息 <div class"right-menu"><templat…

C : DS顺序表--合并操作

Description 建立顺序表的类&#xff0c;属性包括&#xff1a;数组、实际长度、最大长度&#xff08;设定为1000&#xff09; 已知两个递增序列&#xff0c;把两个序列的数据合并到顺序表中&#xff0c;并使得顺序表的数据递增有序 Input 第1行先输入n表示有n个数据&#x…

仿网易云-360度混响

一直在用网易云音乐听歌&#xff0c;感觉他的这个动效还是挺不错的&#xff0c;最近也是想试试canvas绘图相关的。尝试了几次之后感觉效果还不错&#xff0c;不过距离网易云的还是有些差距。 本期准备仿照制作如下效果&#xff1a; 偷偷使用最近比较流行的罗刹海市的音乐来展…

【EasyExcel】excel表格的导入和导出

【EasyExcel】excel表格的导入和导出 【一】EasyExcel简介【二】EasyExcel使用【1】EasyExcel相关依赖【2】写Excel&#xff08;1&#xff09;最简单的写(方式一)&#xff08;2&#xff09;最简单的写(方式二)&#xff08;3&#xff09;排除模型中的属性字段&#xff08;4&…

服务器数据恢复-LINUX操作系统下各文件系统误删除/格式化数据的恢复方案

服务器数据恢复环境&#xff1a; 基于EXT2/EXT3/EXT4/Reiserfs/Xfs文件系统的Linux操作系统。 服务器故障&#xff1a; LINUX操作系统下误删除/格式化数据。 服务器数据恢复过程&#xff1a; 1、首先会检测服务器是否存在硬件故障&#xff0c;如果检测出硬件故障&#xff0c;交…

ARM64 SMP多核启动详解2(psci)

1. 支持psci情况 上面说了pin-table的多核启动方式&#xff0c;看似很繁琐&#xff0c;实际上并不复杂&#xff0c;无外乎主处理器唤醒从处理器到指定地址上去执行指令&#xff0c;说他简单是相对于功能来说的&#xff0c;因为他只是实现了从处理器的启动&#xff0c;仅此而已…

智慧公厕预见幸福生活、美好未来

随着城市化的加速发展&#xff0c;公共厕所作为城市基础设施的重要组成部分&#xff0c;对于提升城市形象和居民生活质量起着至关重要的作用。智慧公厕作为智慧城市建设的一部分&#xff0c;正逐渐成为城市管理的新宠儿&#xff0c;能有效助力网络强国、数字中国、智慧社会的建…

第九章 常用服务器的搭建

第九章 常用服务器的搭建 1.配置FTP服务器 1.1.FTP简介 ​ FTP&#xff08;File Transfer Protocol&#xff0c;文件传送协议&#xff09;是TCP/IP网络上两台计算机间传送文件的协议&#xff0c;FTP是在TCP/IP网络和Internet上最早使用的协议之一&#xff0c;它属于网络协议…

形式化验证方法研究综述

摘要&#xff1a;形式化验证是证明软件、硬件或系统正确性的一种方法&#xff0c;近年来受到了越来越多的关注。 本文对形式化验证的研究进行了综述。首先介绍了形式化验证的基本概念&#xff0c;然后重点介绍了形式化验证的三种技术&#xff0c;包括模型检测、定理证明和等价性…

Redis中是如何实现分布式锁的?

分布式锁常见的三种实现方式&#xff1a; 数据库乐观锁&#xff1b; 基于Redis的分布式锁&#xff1b; 基于ZooKeeper的分布式锁。 本次面试考点是&#xff0c;你对Redis使用熟悉吗&#xff1f;Redis中是如何实现分布式锁的。 要点 Redis要实现分布式锁&#xff0c;以下条件应…

JS基础语法

JS是一门面向对象的编程语言&#xff0c;运行在客户端的脚本语言&#xff0c;可以基于Node.js进行服务器端编程 JS的作用: 表单动态校验网页特效服务端开发 浏览器执行JS&#xff1a; 浏览器分为两部分&#xff1a;渲染引擎和JS引擎 渲染引擎用来解析HTML和CSS&#xff0c;…

2023中国智能产业高峰论坛丨文档图像大模型的思考与探索

# 前言 随着人工智能技术的不断发展&#xff0c;尤其是深度学习技术的广泛应用&#xff0c;多模态数据处理和大模型训练已成为当下研究的热点之一&#xff0c;这些技术也为文档图像智能处理和分析领域带来了新的发展机遇。 近期&#xff0c;2023第十二届中国智能产业高峰论坛…

打印由数字组成的金字塔图案——python

1222 33333 4444444 555555555打印由数字组成的金字塔图案。但n9时&#xff0c;如下图所示。 输入格式: 输入一个整数n&#xff08;1<A<9&#xff09;。 输出格式: 输出由数字组成的金字塔图案。 输入样例: 在这里给出一组输入。例如&#xff1a; 5输出样例: 在这…