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

数据结构3:线性表2-顺序存储的线性表

文章目录

  • 简介
  • 顺序表长度与最大长度之间的关系:
  • 数据类型定义:
  • 线性表API函数及其具体实现:
    • 创建函数:
    • 销毁函数:
    • 清空函数:
    • 长度获取函数:
    • 相应位置元素获取函数:
    • 插入元素函数:
    • 删除元素函数:
    • 小结

简介

作为线性表的一种,顺序存储的线性表(以后简称:顺序表)在存储结构上更像是一种数组,与数组不同的是,它在操作上要复杂一些,但是与线性表的操作一致(毕竟数据表是线性表的一种)。本章节将对顺序表的定义和操作进行详细的讲解和实现。

顺序表长度与最大长度之间的关系:

由于顺序表的存储结构是顺序存储,它的元素存储在一片连续的存储空间。因此,顺序表的最大长度从建立是就已经固定,无法动态的增加或减少。顺序表长度是指顺序表内数据元素的个数,会随着数据元素的插入或删除而增加或减少;最大长度是指存储空间内所允许容纳最多的数据元素的个数。如图1所示:顺序表中是数据元素为E类型的数据,存储区间可容许数据元素个数为8,因此最大数据长度为8;顺序表中的共5个数据元素,因此顺序表的长度为5。需要注意的是,顺序表元素的位置是指相对于表中其他元素的位置,而不是相对于存储区间的位置。
在这里插入图片描述

数据类型定义:

#define LIST_LEN 10 //定义顺序表的最大长度
typedef struct 		 //定义顺表数据类型
{int data;
}element;
typedef struct		//定义线性表数据类型
{int element[LIST_LEN];int length;
}List;

定义顺序表首先需要定义其长度(LIST_LEN),用于规定表中最多元素个数;element为元素类型结构体,包含int 类型的数据data,根据实际应用不同,element的类型可以修改;List是顺序表定义类型,它包含了LIST_LEN个element类型的元素和顺序表长度length。

线性表API函数及其具体实现:

创建函数:

List* ListCreate()
{//新建一个List类型的指针,并将分配空间List *temp = (List *)malloc(sizeof(List));//将顺序表的长度,设置为0temp->length = 0;//返回指针return temp;
}

创建一个顺序表函数的作用是,在堆区分配一个List大小的内存空间,将顺序表长度设置为0。它的数据元素存储区、顺序表长度和存储区间长度关系如图2所示。函数的最后返回一个List 类型的指针,使用时可以先定义一个List类型的指针,将ListCreate函数的返回值赋值给该指针,即完成了顺序表的创建。
在这里插入图片描述
函数应用代码如下:

List * MyList = NULL;//建立一个线性表指针
MyList = ListCreate();//建立一个线性表

销毁函数:

销毁函数的作用是将List 类型指针指向的内存空间释放掉,必将它指向NULL(避免野指针)。函数参数为二级指针,因为我们将要一个指针的值,根据值传和地传的概念,我们只能用二级指针才能修改一级指针的值。

int ListDestory(List **list)
{if (*list == NULL){//如果顺序表是否已经销毁,返回-1return -1;}//释放顺序表内存空间free(*list);//将顺序表指针指向NULL*list = NULL;return 0;
}

函数应用代码如下:

ListDestory(&MyList);

清空函数:

清空函数只是将顺序表内的数据元素清空,因此只要将顺序表的长度清0,数据元素便不会再被访问,即实现清空数据元素;后续的插入覆盖原来的元素实现了元素的插入。

int ListClear(List *list)
{if (list == NULL){//如果输入参数为NULL,返回-1return -1;}//将顺序表长度设置为0list->length = 0;return 0;
}

函数应用代码如下:

ListClear(MyList);

长度获取函数:

长度获取函数的作用是,返回顺序表的长度,便于用户了解此时的顺序表的长度。

int ListGetLength(List *list)
{if (list == NULL){//如果输入参数为NULL,返回-1return -1;}//返回顺序表长度return list->length;
}

函数应用代码如下:

listLen = ListGetLength(MyList);

相应位置元素获取函数:

长度获取函数的作用是将顺序表中相应位置的元素复制一份,通过函数参数将该元素传递出去,如图所示。

int ListGet(List *list, int position,element *ele)
{if (list == NULL || position < 0 || position >= list->length){//如果list为NULL,position小于0或者大于最大长度,返回-1return -1;}*ele = list->member[position];return 0;
}

在这里插入图片描述
函数应用代码如下:

ListGet(MyList,i,&temp);

插入元素函数:

int ListAdd(List *list, int position, element e)
{int i;//判断输入参数是否有误if (list == NULL || position < 0 || position >LIST_LEN){//如果list为NULL,position小于0或者大于最大长度,返回-1return -1;}if (list->length == LIST_LEN){//如果顺序表已满,返回-2return -2;}if (position == list->length){//如果插入位置在末尾,在末尾加入元素list->member[position] = e;//顺序表长度加1list->length++;return 0;}//将从position开始位置的元素向后移动一个位置for (i = list->length; i > position; i--){list->member[i] = list->member[i-1];}//在插入位置插入元素(此时i==position)list->member[i] = e;//顺序表长度加1list->length++;return 0;
}

在这里插入图片描述
在元素进行插入时,首先要进行输入参数的检测,主要是检测指针是否为空,插入位置是否符合要求;然后判断顺序表是否已满,若已满,返回-2,否则继续插入元素。此时元素的插入有两种情况:
第一种:在顺序表末尾插入元素,如图4左侧图所示。因为我们元素下标从0开始,因此,当插入位置position大于或等于顺序表长度时(大于时可插入是为了提高使用方便性,但是严谨性降低,实际使用可以进行调整),表示在表尾部插入,此时将表中相应位置元素赋值即可。在图4左侧图中,顺序表长度为5,我们在下标5处插入新的元素,即实现了顺序表元素的尾部插入,插入成功后,顺序表长度加1,函数返回。
第二种:在顺序表中间位置插入元素,如图4右侧所示。在顺序表中间位置插入元素时,需要先将插入位置及其后面的元素,向后移动一位,然后将插入位置元素赋值为新元素。在图4右侧中,我们要在位置1处插入新的元素,因此需要将E1-E5向后移动一位,移动时从后面的元素开始(从前开始,元素会覆盖丢失),移动到插入位置。移动完成后,在位置1处插入元素,顺序表长度加1,函数返回。
应用代码如下:

ListAdd(MyList,0,data0);
ListAdd(MyList,0,data1);
ListAdd(MyList,0,data2);

删除元素函数:

int ListDelete(List *list, int position,element *e)
{int i;//判断输入参数是否有误if (list == NULL || position < 0 || position >= list->length){//如果list为NULL,position小于0或者大于最大长度,返回-1return -1;}if (list->length == 0){//如果顺序表已空,返回-2return -2;}//保存要删除位置的元素if (e != NULL){*e = list->member[position];}//如果要删除元素在末尾if (position == list->length -1){//顺序表长度减1list->length--;return 0;}//position位置之后,所有的元素向前移动for (i = position; i < list->length -1; i++){list->member[i] = list->member[i + 1];}//顺序表长度减1list->length--;return 0;
}

在这里插入图片描述
元素的删除与元素的插入有类似之处,首先进行输入参数的检测,判断顺序表指针是否为空,判断要删除的元素的位置是正确。如果此时,表中无元素,表长度为0,此时返回错误;否则进行元素删除。元素的删除也分为两种情况,不过在删除前,可以选择将元素取出或者不取出(删除前进行)。
第一种:要删除的元素在顺序表的尾部,如图5左侧图所示。删除前,顺序表长度为5,要删除的元素位置为4。删除元素时,只需要将顺序表长度减1,以后就无法对该位置的元素读取,即实现了元素的删除。
第二种:要删除的元素在顺序表中间位置,只需要将要删除位置元素后面的元素以此前移一位,然后将顺序表长度减1,即实现了元素的删除。
应用代码如下:

ListDelete(MyList,0,NULL);

小结

顺序表结构及其功能函数较为简单,它们的主要功能都是对元素存储位置来实现的。在在顺序表学习中,要理解好存储区间长度和顺序表长度的区别,元素存储位置的变换(特别是在元素插入和删除的时候)。因此,想学好顺序表,首先要对C语言中的数据有较深刻的理解,理解和熟练掌握了数组,顺序表就很简单了!

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

相关文章:

  • TaskIQ 是什么,怎么做异步任务
  • 服务器CPU达到100%解决思路
  • 在 Claude Code 中设置 MCP 服务器(技术总结)
  • 网站上传根目录如何制作线上投票
  • 移动端网站建设的请示东莞科技网站建设
  • EtherCAT转CCLKIE工业通讯网关突破:三菱PLC实时调度EtherCAT伺服完成精密加工
  • 深度学习实验一之图像特征提取和深度学习训练数据标注
  • 基于Matlab的深度堆叠自编码器(SAE)实现与分类应用
  • @Scope失效问题
  • Service 网络原理
  • 数据复制问题及其解决方案
  • Java-Spring入门指南(二十五)Android 的历史,认识移动应用和Android 基础知识
  • WPF依赖属性(Dependency Property)详解
  • 深度学习进阶(三)——生成模型的崛起:从自回归到扩散
  • 三门峡网站开发ict网站建设
  • 神经网络之链式法则
  • C#设计模式源码讲解
  • 性能测试单场景测试时,是设置并发读多个文件,还是设置不同的用户读不同的文件?
  • Qt初识(对象树,乱码问题,小结)
  • 基于Home Assistant的机器人低延迟通信项目详细调研报告
  • 深圳网站做的好的公司婚庆网站开发目的
  • 中小企业网站制作是什么宁德网站建设51yunsou
  • 代理模式 vs AOP:支付服务中的日志增强实践(含执行顺序详解)
  • linux系统运维教程,linux系统运维攻略
  • string字符集
  • Linux 命令:fsck
  • 如何提升生物科技研发辅助的效率?
  • ECEF坐标转换库
  • 企业商务网被公司优化掉是什么意思
  • 网站虚拟主机购买教程专业网站设计工作室