【数据结构】顺序表详解以及实现(C语言实现)

目录

前言:

顺序表的特点:

顺序表简介:

顺序表具体实现:

1.初始化

2.销毁

3.检查空间容量

4.头插和尾插

5.头删和尾删

6.打印

7.指定位置插入

8.指定位置删除

[9. 查找是否有对应元素](#9. 查找是否有对应元素)


顺序表是线性表的存储结构,用一组地址连续的存储单元依次存储线性表的数据元素。在顺序表中,在逻辑结构上连续的,物理结构也连续。一般采用数组储存

顺序表和数组的区别?

顺序表实质上就是对数组的封装,完成了对数组的增删改查的操作。

其实这一张图就能充分解释数组和顺序表的关系


前言:

顺序表的特点:

  1. 存储密度高 :顺序表的每一个节点都有对应的数据元素,没有额外开销,存储密度高
  2. 访问性高 :可以通过首地址然后i根据连续性找到后续相应的元素
  3. 物理位置相邻:物理位置和逻辑位置一致,保持相邻,但这也意味着插入和删除操作可能涉及到大量元素的移动。

顺序表简介:

  1. 顺序表分为静态顺序表和动态顺序表,静态顺序表在结构体中给的是定长数组,缺点很明显,所以我们主要讨论动态顺序表
  2. 动态顺序表主要涉及的内存函数有**malloc()和relloc()**函数。
  3. 动态顺序表主要有初始化,销毁,扩容,头插,尾插,头删,尾删,指定位置插入,查找

顺序表具体实现:

1.初始化

cpp 复制代码
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* arr;
	int size;
	int capacity;

}SL;

void SeqListInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

我们将arr 的首地址定义成NULL,方便之后增加数据,size表示有效数据,capacity表示当前顺序表容量。

2.销毁

cpp 复制代码
void SeqListDestory(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

销毁时,我们先释放顺序表中的数组空间,然后将释放后的指针指向NULL,size和capacity都赋值为0;

3.检查空间容量

cpp 复制代码
void SLCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		int newcapactity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, sizeof(ps->capacity));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);

		}
		ps->arr = tmp;
		ps->capacity = newcapactity;
	}

}

当size和capacity相等时,说明空间满了,如果在想加入数据,需要进行扩容,这时候就要用到realloc函数了,对现有空间进行扩容,代码意思是申请ps->capacity个字节数的类型为SLDataType*的空间给ps->arr上。

4.头插和尾插

cpp 复制代码
void SeqListPushBack(SL* ps, SLDataType x)//尾插

{

	assert(ps);
	SLCheckCapacity(ps);
   ps->arr[ps->size++] = x;
}//因为size的位置总是在最后一位有效元素的下一个位置的,所以直接插入就好



void SeqListPushFront(SL* ps, SLDataType x)//头插
{
	assert(ps);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];

	}
	ps->arr[0] = x;
	ps->size++;


}//头插需要将所有现有元素向后移动一位,在下标为0的元素插入

5.头删和尾删

cpp 复制代码
void SeqListpopBack(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
//ps->arr[ps->size - 1] = -1;
	ps->size--;
}//对size直接进行--即可
void SeqListpopFront(SL* ps, SLDataType x)
{
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i + 1];


	}
	ps->size--;
}//头删需要将所有元素向前移动一位即可,有效数据进行--

6.打印

cpp 复制代码
void SeqListprint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d", ps->arr[i]);

	}
	printf("\n");
}

7.指定位置插入

cpp 复制代码
void SeqListInsert(SL* ps, int pos, SLDataType x)//顺序表指定位置插入
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];

	}
	ps->arr[pos] = x;
	ps->size++;
}//pos位置之后的位置进行向后移动一位,然后再下表为pos位置进行插入

8.指定位置删除

cpp 复制代码
void SeqListErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	for (int i = ps->size; i < pos; i++)
	{
		ps->arr[i - 1] = ps->arr[i];

	}
	ps->size--;



}//pos之后的向前移动一位,将pos位置的值进行覆盖,有效数据-1;

9. 查找是否有对应元素

cpp 复制代码
int SeqListFind(SL* ps, SLDataType x)

{
	int flag = 1;
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->arr[i] == x)
		{

			flag = 0;
			return x;

		}


	}
	return -1;


}//遍历顺序表中的所有有效数据,如果与查找的数相等,直接返回查找数,遍历完毕之后,没有发现,返回-1

相关推荐
稚辉君.MCA_P8_Java6 分钟前
Gemini永久会员 Go 返回最长有效子串长度
数据结构·后端·算法·golang
TL滕14 分钟前
从0开始学算法——第五天(初级排序算法)
数据结构·笔记·学习·算法·排序算法
Ayanami_Reii24 分钟前
进阶数据结构应用-线段树扫描线
数据结构·算法·线段树·树状数组·离散化·fenwick tree·线段树扫描线
浅川.2529 分钟前
xtuoj 素数个数
数据结构·算法
少许极端1 小时前
算法奇妙屋(十五)-BFS解决边权为1的最短路径问题
数据结构·算法·bfs·宽度优先·队列·图解算法·边权为1的最短路径问题
不穿格子的程序员2 小时前
从零开始写算法——普通数组类题:数组操作中的“翻转技巧”与“前后缀分解”
数据结构·算法
curry____3032 小时前
study in PTA(高精度算法与预处理)(2025.12.3)
数据结构·c++·算法·高精度算法
代码游侠2 小时前
学习笔记——栈
开发语言·数据结构·笔记·学习·算法
Ayanami_Reii2 小时前
进阶数据结构应用-维护序列
数据结构·算法·线段树
CoderYanger2 小时前
C.滑动窗口-越长越合法/求最短/最小——2904. 最短且字典序最小的美丽子字符串
java·开发语言·数据结构·算法·leetcode·1024程序员节