一文了解顺序表(小白必看)

线性表的顺序表示

1线性表和顺序表的定义

​ **(1)线性表:**线性表是具有相同数据类型的 n(n≥0)个数据元素的有限序列。

​ **(2)顺序表:**用顺序存储的方式实现线性表 顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

2静态分配和动态分配

2.1静态分配

​ (1)没有反映元素个数n和表的内在联系

#define MAX 100
ElemType elem[MAX];		 	//表
int n; 						//数据元素个数n<MAX

​ (2)用结构体将顺序表的相关信息封装起来

#define MAX 100 			//最大元素个数
typedef struct
{
	ElemType elem[MAX];
	int length; 			//元素个数,即表长
}Sqlist;
2.2动态存储
#define LIST_INIT_SIZE 100 		//存储空间的初始分配量
#define LISTINCREMENT 10 		//分配增量
typedef struct
{
	ElemType *elem; 			//存储区域的基址
	int length; 				//当前表的长度
	int listsize;				//当前已分配的存储容量
)SqList;						//顺序表类型

​ (1)动态申请和释放内存空间

​ (2)C——malloc、free函数

​ L.data = (ElemType *) malloc (sizeof(ElemType) * InitSize

​ malloc 函数的参数,指明要分配多大的连续内存空间;malloc 函数返回一个指针,需要强制转型为自己定义的数据元素类型指针。

​ (3)C++ —— new、delete 关键字

2.3顺序表基本操作的实现
1.初始化顺序表 InitList_Sq( &L )

操作结果:构造一个空的顺序表 L。

Status InitList_Sq (SqList &L) 		//构造一个空的顺序表 L
{
	L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
	if(!L.elem)
		exit(OVERFLOW); 			//存储空间分配失败
	L.length=0;
	L.listsize=LIST_INIT_SIZE;
	return OK;
} 									//InitList_sq

​ 算法的时间复杂度:O(1)。

2.销毁顺序表 DestroyList_Sq (&L):

操作结果:释放 L 占用的内存空间。

void DestroyList_Sq(SqList &L)
{
	free(L.elem);
	L.elem=NULL;
	L.length=0;
	L.listsize=0;
}

3.判定是否为空表 ListEmpty_Sq( L ):

操作结果:若 L 为空表,则返回 1,否则返回 0。

int ListEmpty_Sq(SqList L)
{
	return(L.length == 0);
}
4.输出顺序表 DispList_Sq ( L ):

操作结果:当 L 不为空时,顺序显示 L 中各元素的值。

Status DispList_Sq(SqList L)
{
	if(ListEmpty_Sq(L))
	return ERROR;
	for(i=0; i<L.length; i++)
		printf(L.elem[i]);
	return OK;
}
5.插入数据元素 ListInsert_Sq (&L, i, e):

操作结果:在顺序表 L 的第 i 个位置(1≤i≤L.length+1)前插入新元素 e。

Status ListInsert_Sq(SqList &L, int i, ElemType e)
{ 								//在顺序表 L 中第 i 个位置之前插入数据元素 e
	if(i<1||i>L.length+1)
		return ERROR;			//i 值不合法
	if(L.Length>=L.listsize){ 	//上溢时,增加空间
		newbase=(ElemType*)realloc(L.elem,	(L.listsize+LISTINCREMENT)*sizeof(ElemType));
	if(!newbase)
		exit(OVERFLOW); 		//存储分配失败
	L.elem=newbase;
	L.listsize+=LISTINCREMENT;
} //if
	for(j=L.length; j>=i; j--)
		L.elem[j]=L.elem[j-1]; 	//元素后移(从最后一个元素开始)
	L.elem[i-1]=e; 				//在位置 i 处插入元素 e(注意位序与 elem 下标)
	++L.length; 				//顺序表长度增 1
	return OK;
}

时间复杂度:

最好情况: 新元素插入到表尾,不需要移动元素 i = n+1,循环 0 次;最好时间复杂度= O(1)

最坏情况: 新元素插入到表头,需要将原有的 n 个元素全都向后移动 i = 1,循环 n 次;最

坏时间复杂度= O(n);

平均情况: 假设新元素插入到任何一个位置的概率相同,则长度为 n 的线性表中插入一个

结点时,所需节点的移动次数为:
∑ i = 1 n + 1 p i ( n − i + 1 ) = ∑ i = 1 n + 1 1 n + 1 ( n − i + 1 ) = 1 n + 1 ∑ i = 1 n + 1 ( n − i + 1 ) = 1 n + 1 n ( n + 1 ) 2 = n 2 \sum_{i=1}^{n+1} p_{i}(n-i+1) = \sum_{i=1}^{n+1}\frac{1}{n+1}(n-i+1) = \frac{1}{n+1}\sum_{i=1}^{n+1}(n-i+1) = \frac{1}{n+1}\frac{n(n+1)}{2} = \frac{n}{2} i=1n+1pi(ni+1)=i=1n+1n+11(ni+1)=n+11i=1n+1(ni+1)=n+112n(n+1)=2n
平均时间复杂度= O(n)

6.删除数据元素 ListDelete_Sq ( &L, i, &e):

操作结果:删除顺序表 L 中的第 i(1≤i≤L.length)个元素,用引用变量 e 返回删除的元素。

Status ListDelete_Sq(SqList &L, int i, ElemType &e)
{
	if(i<1||i>L.length)
		return ERROR;				 //合法位置?
	e=L.elem[i-1];
	for(j=i; j<L.length; j++)
		L.elem[j-1]=L.elem[j]; 		//元素前移(从第 i+1 个位置开始)
	--L.length; 							//顺序表长度减 1
	return OK;
}

时间复杂度:

最好情况: 删除表尾元素,不需要移动其他元素 i = n,循环 0 次;最好时间复杂度=O(1)

最坏情况: 删除表头元素,需要将后续的 n-1 个元素全都向前移动 i = 1,循环 n-1 次;最

坏时间复杂度=O(n);

平均情况: 假设删除任何一个元素的概率相同,则长度为 n 的线性表中插入一个结点时,

所需节点的移动次数为:
∑ i = 1 n p i ( n − i ) = ∑ i = 1 n 1 n ( n − i ) = 1 n n ( n − 1 ) 2 = n − 1 2 \sum_{i=1}^{n}p_i(n-i)=\sum_{i=1}^{n}\frac{1}{n}(n-i)=\frac{1}{n}\frac{n(n-1)}{2}=\frac{n-1}{2} i=1npi(ni)=i=1nn1(ni)=n12n(n1)=2n1
平均时间复杂度=O(n)

7.按位查找操作 GetElem(L,i):

操作结果:获取表 L 中第 i 个位置的元素的值。

ElemType GetElem(SeqList L, int i)
{
	return L.data[i-1];
}

时间复杂度:O(1)

8.按值查找操作 LocateElem(L,e):

操作结果:在表 L 中查找具有给定关键字值的元素(第一个)。

//在顺序表 L 中查找第一个元素值等于 e 的元素,并返回其位序
int LocateElem(SeqList L,ElemType e)
{
	for(int i=0;i<L.length;i++)
		if(L.data[i]==e)
			return i+1; 	//数组下标为 i 的元素值等于 e,返回其位序 i+1
	return 0;				//退出循环,说明查找失败
}

时间复杂度:

最好情况: 目标元素在表头,循环 1 次;最好时间复杂度=O(1)

最坏情况: 目标元素在表尾,循环 n 次;最坏时间复杂度=O(n);

平均情况: 假设目标元素出现在任何一个位置的概率相同,则在长度为 n 的线性表中

查找值为 e 元素所需的平均次数为:
∑ i = 1 n p i × i = ∑ i = 1 n 1 n × i = 1 n n ( n + 1 ) 2 = n + 1 2 \sum_{i=1}^{n}p_i×i=\sum_{i=1}^{n}\frac{1}{n}×i=\frac{1}{n}\frac{n(n+1)}{2}=\frac{n+1}{2} i=1npi×i=i=1nn1×i=n12n(n+1)=2n+1
平均时间复杂度=O(n)

2.4 顺序表基本操作的总结

请添加图片描述

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值