线性表的顺序存储

线性表的顺序存储结构(又称随机存储结构)

顺序存储:依次存储

特性:没数据还占座

结构代码
#define MAXSIZE 20
typedef int ElemType;  //整型的
typedef struct
{
	ElemType data[MAXSIZE];
	int length;
}SqList;
封装的三个属性:
1. 存储空间的起始位置,数组data (座位)
2.最大存储容量:数组的长度MaxSize (一般初始化不变,若变,需动态扩容,可能降低性能)
3.length:当前线性表的长度 (时刻可变,只看元素个数)

地址计算方法(线性表是从1开始的)
ElemType 占用c个存储单元(字节),存储位置关系:LOC(i+1)=LOC(i)+ c;

元素 1 2 3 4 5 n
数组 0 1 2 3 4 n-1

第n个元素的位置=第1个元素的位置 + (n-1)*c  

可通过公式 一次 计算出存储地址,存储时间性能为 O(1)


顺序存储结构的优缺点:

在存、读数据时(GetElem操作),任何位置时间复杂度都是O(1)。插入或删除时(只考虑平均情况),时间复杂度为O(n)。

说明,顺序结构适合元素个数比较稳定的存取应用,不经常插入和删除元素。

优点:

1.不需要为元素之间的逻辑关系增加额外的存储空间;

2.可以快速存取表中任意位置的元素。

缺点:

1.插入和删除需要移动大量元素;

2.若线性表长度变化较大,难以确定存储空间的容量。

3.易生成存储空间的碎片(由于顺序存储申请空间是连续的)

--------------------------------------------------------------------------------------------------------------------------------

有待增加

problem1.为什么插入、删除需要移动大量数据?

由于相邻元素的存储位置具有邻居关系,在内存中的位置也是相邻的,中间没有缝隙,导致只能整体移动,无法快速插入和产出

------------------------------------------------------------------------------------------------------------------------------------------------------------


GetElem操作
将线性表中第i个位置元素值返回->将数组第i-1下标 值返回;

具体见 getelem.cpp

getelem.cpp
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
// Status 函数类型,值为函数结果状态,eg ok;

Status GetElem(SqList L, int i, ElemType *e)
{
	if(L.length == 0 || i>L.length)
	{
		return ERROR;
	}
	*e = L.data[i-1];
	return OK;
} 

ListInsert操作
思路:
1.插入位置不合理,抛出异常
2.线性表长度大于等于数组长度--》没有插入的位置,抛出异常,或动态增加数组容量
3.从最后一个 位置向前遍历到第i个位置,分别将它们都向后移动一个位置
4.将插入元素放到i处
5.线性表长度+1

具体见cpp

ListInsert.cpp
//初始条件:顺序线性表L存在,1<i<ListLengh(L)
//操作结果:在L中第i个位置之前插入新的数据元素e L长度+1 
Status ListInsert(SqList *L,int i,ElemType e)
{
	int k;
	if(L->lengh == MAXSIZE)  //线性表已满
	{
		return ERROR;
	} 
	if(i<1 || i>L->length+1) // 当i不在范围之内
	{
		return ERROR;	
	} 
	if (i<= L->length )
	{
		for(k= L->length-1; k>= i-1;k--)  //将最后一位到要插入位置 元素全部向后移一位
		{
			L->data[k+1]=L->data[k];
		} 
	}
	L->data[i-1]=e;
	L->length++;
	return OK;
}
	

1.如果删除位置不合理,抛出异常

2.取出删除元素

3.从删除元素位置开始遍历到最后一个元素位置,分别将他们向前移动一个位置

4.表长减一

delete.cpp
/*初始条件:顺序线性表L已存在,1<=i<=ListLength(L)*/
/*操作条件:删除L的第i个元素,并用e返回其值,L的长度-1*/
Status ListDelete(SqList *L,int i,ElemType *e)
{
	int k;
	if (L->length==0)    //空表 
	return ERROR;
	if (i<1 || i < L->length)  //删除元素的位置不对 
	{
		return ERROR;
	}
	*e = L->data[i-1];
	if (i < L->length)
	{
		for(k=i; k < L->length ; k++)
		{
			L->data[k-1]=L->data[k];   //每个元素从i开始,依次向前移动一位 
		}
	}
	L->length--;    //表长减一 
	return OK;
} 

插入和删除时间复杂度

1.最好的情况:插入和删除元素刚好在最后一位,不需要移动任何元素,时间复杂度为O(1);

2.最坏的情况:插入和删除元素在第一位,则整个线性表中的元素都要移动,时间复杂度为O(n);

3.平均情况:时间复杂度为最好、最坏的中间值,O((n-1)/2),简化后还是O(n)。




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值