数据结构之——《顺序表》

本文介绍了顺序表,它是用连续存储单元存储数据元素的线性结构,一般用数组存储。顺序表分为静态和动态两种。文中给出顺序表初始化、容量检查等接口函数的代码示例,还分析了顺序表的优缺点,如支持随机访问,但插入删除复杂度高、增容代价大。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



1.含义

顺序表示用一段纹理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。

2.分类

顺序表一般分为:
(1)静态顺序表:使用定长数组存储
(2)动态顺序表:使用动态开辟的数组存储

3.接口函数实现

(0)顺序表的初始化
代码如下(示例):

void initSeqList(seqList* s1)
{
	s1->_data = NULL;
	s1->_size = s1->_capacity = 0;
}

(1)容量检查
代码如下(示例):

void checkCapacity(seqList* s1)
{
	//assert(s1);//debug版本有效,调试版本用if是否为空
	if (s1 == NULL){
		return;
	}
	if (s1->_size == s1->_capacity){
		int newCapacity = s1->_capacity == 0 ? 1 : 2 * s1->_capacity;
		//开辟一个更大的空间,拷贝已有数据,释放原有的空间
		SLDataType* tmp = (SLDataType*)malloc(sizeof(SLDataType)*newCapacity);
		memcpy(tmp,s1->_data,sizeof(SLDataType)*s1->_size);
		free(s1->_data);
		//另一种开辟空间拷贝数据释放原空间的代码
		//s1->_data = (SLDataType*)realloc(s1->_data,sizeof(SLDataType)*newCapacity)
		
		//更新
		s1->_data = tmp;
		s1->_capacity = newCapacity;
	}
}

(2)顺序表打印
代码如下(示例):

void printSeqList(seqList*s1)
{
	for (int i = 0; i < s1->_size; ++i){
		printf("%d ",s1->_data[i]);
	}
	printf("\n");
}

(3)顺序表头插一个元素
代码如下(示例):

void pushFront(seqList* s1, SLDataType val)
{
	if (s1 == NULL){
		return;
	}
	//0.检查容量
	checkCapacity(s1);
	//1.移动元素[0,size)全部向后移动一个位置,
	//方向:从后向前依次移动,否则会导致数据被覆盖
	int end = s1->_size;
	while (end > 0){
		s1->_data[end] = s1->_data[end - 1];
		--end;
	}
	//2.头插一个元素
	s1->_data[0] = val;
	//3.更新size
	s1->_size++;
}

(4)顺序表头删一个元素
代码如下(示例):

void popFront(seqList* s1)
{
	if (s1 == NULL||s1->_size==0){
		return;
	}
	//1.头删,数据从前往后移动,否则数据会被覆盖
	int start = 1;
	while (start < s1->_size){
		s1->_data[start - 1] = s1->_data[start];
		++start;
	}
	--s1->_size;
}

(5)顺序表尾插一个元素
代码如下(示例):

void pushBack(seqList* s1, SLDataType val)
{
	//先检查容量是否可以满足插入一个数据
	checkCapacity(s1);
	s1->_data[s1->_size] = val;
	++s1->_size;
}

(6)顺序表尾删一个元素
代码如下(示例):

void popBack(seqList* s1)
{
	if (s1 == NULL){
		return;
	}
	if (s1->_size > 0){
		s1->_size--;
	}
}

(7)在任意位置pos插入一个元素
代码如下(示例):

void insert(seqList* s1, int pos, SLDataType val)
{
	if (s1 == NULL){
		return;
	}
	if (pos >= 0 && pos <= s1->_size){
		//检查容量
		checkCapacity(s1);
		//移动元素:[pos,size),从后向前移动,
		int end = s1->_size;
		while (end> pos){
			s1->_data[end] = s1->_data[end - 1];
			--end;
		}
		//插入数据
		s1->_data[pos] = val;
		//更新
		s1->_size++;
	}
}

(8)在任意位置pos删除一个元素
代码如下(示例):

void erase(seqList* s1, int pos)
{
	if (s1 == NULL || s1->_size == 0){
		return;
	}
	//有效位置:[0,size)
	if (pos >= 0 && pos < s1->_size){
	//移动元素:(pos,size)
	//从pos+1开始,从前向后移动
		int start = pos + 1;
		while (start < s1->_size){
			s1->_data[start - 1] = s1->_data[start];
			++start;
		}
		--s1->_size;
	}
}

4.顺序表的优缺点

优点:
(1)空间连续,支持随机访问。
缺点:
(1)中间或前面部分的插入删除时间复杂度为o(N)。
(2)增容的代价比较大。增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗,而且增容一般是呈2倍的增长,务必会有一定的空间浪费。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值