数据结构02 顺序表基本操作大全

特征

  • 除首尾元素外每个数据元素只有一个前驱,一个后继
  • 线性表长度为0时,为空表
  • 支持插入,删除,取值等基本运算

具体实现

顺序存储

线性表中第i个元素的存储位置满足
L o c ( a i ) = L o c ( a 0 ) + l × i Loc(a_i) = Loc(a_0) + l\times i Loc(ai)=Loc(a0)+l×i

具体操作
  • 初始化:动态分配内存
#define MAX_TERMS 100 // 最大项数
typedef struct{
	int* num;
	int length;
}SqList; 

void init(SqList* l){             //传指针
	l->num = (int*)malloc(MAX_TERMS*sizeof(int));
	l->length = 0;
}
  • 取值:需要判断索引值是否有效
int GetElem(SqList l,int i){
	if(i > 0 && i< l.length)
		return l.num[i-1];
	else
		return -1;                  
}
  • 查找:遍历
int LocateElem(SqList l,int e){
	for(int i = 0;i < l.length;i++){
		if(e == l.num[i])
			return i+1;
	}
	return -1;
}

定义平均查找长度为ASL, P i P_i Pi 为查找到第i个元素概率, C i C_i Ci 为元素在表中位置
A S L = ∑ i = 1 n p i C i ASL = \sum_{i=1}^np_iC_i ASL=i=1npiCi
若每个元素查找概率相等,均为 1 n \frac{1}{n} n1,则ASL可进一步简化为 n + 1 2 \frac{n+1}{2} 2n+1
故该查找算法平均时间复杂度为 O ( n ) O(n) O(n)

  • 插入
    第1至length+1个位置均为合法插入位置(位置与线性表实际下标不同)
    在第i个元素位置插入,即原线性表第i个元素前
    将第1至length位置处元素依次向后移一个位置,空出第i个位置
void ListInsert(SqList* l,int i,int e){
	if(i < 1||i > l->length+1) 					//invalid index
		return;
	if(l->length == MAX_TERMS)                  //overflow
		return;
	for(int j = l->length-1;j >= i-1;j--){
		l->num[j+1] = l->num[j];
	}
	l->num[i-1] = e;
	l->length++;
}

顺序表插入元素的时间复杂度也为 O ( n ) O(n) O(n)

  • 删除
void ListDelete(SqList* l,int i){
	if(i < 1 && i > l->length)
		return;
	for(int j = i-1;j < l->length-1;j++){
		l->num[j] = l->num[j+1];
	}
	l->length--;
}

顺序表删除元素的时间复杂度也为 O ( n ) O(n) O(n)

  • 两线性表合并
void merge(SqList* a,SqList* b){
	int temp;
	for(int i = 0;i < b->length;i++){
		temp = b->num[i];
		if(LocateElem(*a,temp) == 0)
			ListInsert(a,a->length+1,temp);
	}
}

下面补充show函数并依次进行检验

void show(SqList l){
	for(int i = 0;i < l.length;i++){
		printf("%d%c",l.num[i],(i==l.length-1?'\n':'\t'));
	}  
}

int main(){
	SqList SL;
	init(&SL);
	
	for(int i = 0;i < 5;i++){
		ListInsert(&SL,i+1,i);
	} 
	printf("第一次插入:\n"); 
	show(SL);
	printf("第二次插入:\n"); 
	ListInsert(&SL,2,100);
	show(SL);
	printf("删除:\n"); 
	ListDelete(&SL,2);
	show(SL);
	printf("取值:\n");
	int e = GetElem(SL,2);
	printf("%d\n",e);
	printf("合并:\n");
	SqList TMP; 
	init(&TMP);
	for(int i = 5;i < 10;i++){
		ListInsert(&TMP,i-4,i);
	} 
	merge(&SL,&TMP);
	show(SL);
	return 0;
}

输出依次为

第一次插入:
0       1       2       3       4
第二次插入:
0       100     1       2       3       4
删除:
0       1       2       3       4
取值:
1
合并:
0       1       2       3       4       5       6       7       8       9
顺序表弊端
  • 存储空间预先分配,元素扩充受限制,且易造成溢出
  • 可能造成空间浪费
  • 插入,删除操作需移动大量元素

因此,当线性表长度变化小,且可事先确定长度时,使用顺序表

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值