数据结构之线性表(顺序存储结构)

目录


前言

学习了本章线性表,我们应该知道什么是线性表,能够判断一张表是不是线性表。重点是掌握线性表了两种存储结构,以及在分别用这两种存储结构创建一张线性表,并且在这两种结构中对表进行查找、增加、删除等等操作;对比这两种存储结构的优缺点,知道在什么情况下用哪种结构。


一、介绍线性表

线性表:线性表是由一系列有序元素组成的数据结构,每个元素都有唯一的前驱和后继。

上图就是一个简单的线性表,其中a1是a2唯一的直接前驱,a2是a1唯一的直接后继;注意头节点和尾节点分别没有直接前驱和直接后继。

判断一个表是不是线性表就看他的每个元素的直接前驱和直接后继是不是只有唯一一个;

某些比较复杂的线性表的一个数据元素可以由多个数据项组成,如下表:

姓名班级学号
张三1班123
李四1班

456

线性表的长度就是表中元素个数的总和;可以为空表,即长度为0。

二、线性表的顺序存储结构

1.顺序存储定义

1.用一段连续的存储空间,将数据元素存储到连续且按顺序排列的内存单元内。

2.存储方式:数组

创建一张线性表,代码如下:

#define MAXSIZE 10     //确定数组长度 
typedef int ElemType; //ElemType类型根据实际情况而定 
typedef struct{       
	ElemType data[MAXSIZE];//定义数组 
	int length;           //线性表长度 
}SqList;                 //线性表名 

3.这里注意区分一下数组长度和线性表长度:

  • 数组长度是定义的数组的长度,也就是存储空间的大小。
  • 线性表长度是线性表示数据元素的个数,一般要小于数组的长度。

4.地址计算

这里地址用LOC()来表示,假设第一个元素a1的位置已知为0,每个数据元素占用c个存储单元

2.顺序结构存储操作

1.查找

这里查找第线性表中第i个元素的值,代码如下:(C语言版)

#define OK 1
#define ERROR 0
typedef int Status;
Status GetElem(SqList L,int i,ElemType *e){
	if(L.length ==0||i<0||i>L.length )       //如果为空表或者查找的范围不在线性表的长度之内
	return ERROR;                            //满足以上条件其中一个,则直接返回ERROR,查找失败  
	*e=L.data [i-1];                         //否则将其值赋值给*e(注意这里如果不用*e,则在主函数中e的值无法修改,需要return e;才能获得目标值) 
	return OK;                               //查找成功 
}

我的建议是各位同学可以先分析一下以上代码,然后看上面是算法步骤(此时就不要看代码了)自己去敲一次,实在敲不出来再来看代码 

2.插入

算法:

  1. 判断插入位置是否合理,不合理则返回失败
  2. 判断数组空间是否能容纳下线性表,确保不会超出数组的空间范围
  3. 从要插入位置的元素及以后的所有元素向后挪一位
  4. 将新的元素插入
  5. 表长+1                                                                                                                                 

代码如下:(C语言版)

Status ListInsert(SqList *L,int i,ElemType e){
	int k=L->length;
	if(i<1||i>L->length +1)//插入的位置比线性表第一个元素数据的位置还小,或者在最后一个位置的后一个位置的后一个位置
	return  ERROR;//返回失败
	if(L->length >=MAXSIZE)//数组空间不够 
	return ERROR;//返回失败
	for(i;i<=k;k--){//因为要把第i个位置的元素也往后挪,所以这里i要小于等于表长 
		L->data[k]=L->data [k-1];//从最后一个元素往后挪,直到将第i个元素挪完以后停止 
	}
	L->data [i-1]=e;//将e插在第i个元素的位置 
	L->length ++;//由于加进了一个元素,所以表长加一 
	return OK;//操作成功 
} 

我的建议是各位同学可以先分析一下以上代码,然后看上面是算法步骤(此时就不要看代码了)自己去敲一次,实在敲不出来再来看代码

3.删除

这里的删除就是一种覆盖,将要删除元素位置后边的值赋值给他,将原来的值覆盖掉,然后后面的位置接着做这个操作,直到最后。

算法:

  1. 判断删除位置是否合理
  2. 去除返回的元素,并将他记录下来
  3. 删除位置以后的每个元素都向前挪一位
  4. 表长减一

代码如下:


Status ListDlete(SqList *L,int i,ElemType *e){
	if(L->length ==0)//如果此表为空则没有删除的元素 
	return ERROR;//返回失败
	if(i<0||i>L->length +1)//删除的位置比线性表第一个元素数据的位置还小,或者比最后一个位置的后一个位置的后一个位置还大 
	return ERROR;//返回失败
	*e=L->data [i-1];//记录将要删除的元素 
	for(i;i<L->length ;i++){
		L->data [i-1]=L->data [i];//将i位置以后的每个元素都往前挪 
	} 
	L->length --;//表长减一 
	return OK;//操作成功 
}

我的建议是各位同学可以先分析一下以上代码,然后看上面是算法步骤(此时就不要看代码了)自己去敲一次,实在敲不出来再来看代码 

三、顺序存储的优缺点

1.优点

  1. 表中元素的逻辑结构和物理结构一致,不用再想办法来处理逻辑结构。
  2. 可以快速查找获得表中任意元素的位置

2.缺点

  1. 插入和删除操作需要挪动大量元素
  2. 难以事先确定好存储空间的大小

总结

线性表是一种常见的数据结构,它按照线性的顺序存储数据元素。顺序存储结构是线性表的一种实现方式,通过数组等连续的存储单元来存储元素。

综合而言,顺序存储结构适用于对元素的随机访问较多、插入和删除操作较少的场景。在对空间利用要求不是特别苛刻的情况下,顺序存储结构是一种高效的实现方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值