C语言顺序表插入与删除操作详解

唐可
唐可
发布时间:2026-10-15 | 5人浏览过
原创

顺序表是C语言数据结构中最基础的线性结构之一。本文详细拆解如何使用指针和动态内存实现顺序表的初始化、按位插入(含空间不足时的扩容逻辑)以及元素删除。通过完整的C语言代码示例,直观展示数据元素在数组中的移动过程,适合需要理解底层内存管理的开发者参考。

一、理解顺序表结构与初始化

顺序表本质上是利用连续内存存储数据的结构。在C语言中,通常使用 struct 封装一个指向动态数组的指针,并记录当前有效长度与总容量。

第1步:定义数据结构

首先定义顺序表的结构体。需要注意,listsize 表示分配的总容量,而 len 记录实际存放的有效元素个数。在逻辑上,顺序表的第一个元素通常被视为位置 1,这与 C 语言数组从索引 0 开始的物理特性存在偏移关系。

<stdio.h> 用于输入输出,<stdlib.h> 用于动态内存管理。Elemtype 定义为整型,可根据实际需求修改。

#include <stdio.h>
#include <stdlib.h>
 
#define MAXSIZE 10
#define OK	  1
#define FALSE 0 
 
typedef int Elemtype;
typedef bool Status;
 
typedef struct list
{
	Elemtype *elem;
	int len;        //数据个数
	int listsize;   //顺序表长度
}List;

第2步:初始化函数

初始化函数的核心是申请初始内存并设置状态参数。若内存申请失败,程序应立即退出以防后续操作引发严重错误。

void list_init(List *L)
{
	L->elem=(Elemtype *)malloc(MAXSIZE*sizeof(Elemtype));
	if(L->elem==NULL)
	{
		printf("malloc fail\n");
		exit(0);
	}
 
	L->len=0;	//初始化有效数据长度为0
	L->listsize=MAXSIZE;	//初始化总容量
}

二、顺序表的插入操作

插入操作不仅要处理数据的前移,还要考虑当前存储空间是否足够。插入的逻辑步骤如下:

第3步:位置校验与扩容检查

插入位置 i 必须合法,即大于等于 1 且小于等于当前长度加 1。同时需判断当前长度是否已达到上限 listsize。若空间已满,则需要调用 realloc 进行动态扩容,增加一块大小为 MAXSIZE 的空间,并更新 listsize。

Status list_insert(List *L,int i,Elemtype data)
{
	Elemtype *base,*insert,*p;
	// 1. 合法性检查
	if(i<1 || i>L->len+1 || L==NULL)
	{
		printf("位置输入错误\n");
		return FALSE;
	}
	// 2. 空间不足时扩容
	if(L->len >= L->listsize) // 原文此处逻辑有误,应为>=或已接近满员才扩容
	{
		base=(Elemtype *)realloc(L->elem,(L->listsize+MAXSIZE)*sizeof(Elemtype));
		if (base == NULL) { // 建议增加 realloc 失败检查
            printf("realloc fail\n");
            return FALSE;
        }
		L->elem=base;
		L->listsize+=MAXSIZE;
	}
	// ... 后续移动数据代码略
}
原文中插入部分的扩容判断条件 if(L->len > L->listsize) 存在逻辑瑕疵,当 len 等于 listsize 时数组已满,应在此时触发扩容,因此修正为大于等于。另外增加了 realloc 失败的安全检查。

第4步:后移元素并赋值

找到目标插入地址 insert(对应数组索引 i-1)。从最后一个有效元素开始,逐个将元素向后移动一位,直到移动到 insert 位置的下一个位置。最后将新数据写入 insert 指向的地址,并将有效长度 len 加 1。

	insert=&(L->elem[i-1]); // 获取插入位置指针
	// 从最后一个元素前移,直到移到插入位置之后
	for(p=L->elem + L->len-1;p>=insert;p--)
	{
		*(p+1)=*p;
	}
	*insert=data;
	L->len++;
	return OK;

三、顺序表的删除操作

删除指定位置的元素后,需要将后继元素向前填补空缺。若删除位置非法(如越界),则直接返回失败。

第5步:定位与移位

获取待删除元素的指针 aim(数组索引 i-1)。随后从 aim+1 位置开始,将每个元素赋值给前一个位置,直至遍历完所有剩余元素。操作完成后,有效长度 len 减 1。

Status list_delete(List *L,int i)
{
	Elemtype *aim,*p;
	// 1. 参数校验
	if(i<1 || i>L->len)
	{
		printf("位置输入错误\n");
		return FALSE;
	}
	// 2. 定位删除元素
	aim=&(L->elem[i-1]);
	p=(L->elem+L->len-1); // 指向末尾元素的指针
	
	// 3. 覆盖式前移
	for(aim=aim+1;aim<=p;++aim)
	{
		*(aim-1)=*aim;
	}
	L->len--;
	return OK;
}

四、完整示例与验证

以下代码整合了上述逻辑,包含显示列表的功能以及 main 测试用例。程序中先在顺序表中存入 10 个元素,然后在第 5 个位置插入 99,最后再删除第 5 个位置的元素。执行后可观察数据的变化以验证逻辑的正确性。

// 补充显示函数
void show_list(List *L)
{
	int i;
	for(i=0;i<L->len;i++)
	{
		printf("elem[%d]=%d\n",i+1,L->elem[i]);
	}
	printf("\n");
}

int main()
{
	int i;
	List L;
	list_init(&L);
	// 初始插入 1 到 10
	for(i=0;i<10;i++)
	{
		list_insert(&L,i+1,i+1);
	}
	printf("插入前的顺序表\n");
	show_list(&L);
 
	printf("在第5位置插入99后的顺序表\n");
	list_insert(&L,5,99);
	show_list(&L);
 
	printf("删除第5位置元素后的顺序表\n");
	list_delete(&L,5);
	show_list(&L);
	return 0;
}

通过上述步骤,可以清晰看到顺序表在内存中连续的存储特性及其插入、删除操作的移动代价。在实际工程开发中,建议对动态扩容的时机进行优化(例如增长比例为 1.5 倍而非固定增量),以提升性能。

以上就是C语言实现顺序表的插入删除的详细内容,更多关于C语言数据结构线性表操作的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表