顺序表的基本操作(C语言实现)

本文详细介绍了顺序表的概念,包括静态顺序表和动态顺序表的实现。静态顺序表使用定长数组,而动态顺序表在内存不足时会自动增容。文中给出了动态顺序表的基本操作实现,如初始化、增容、尾插、尾删、头插、头删、查找、插入、删除、销毁和打印等,并提供了示例代码。动态顺序表在实际应用中更为常见。
摘要由CSDN通过智能技术生成

顺序表

**前言:**本文主要讲线性表的其中一种,那就是顺序表。顺序表就是采用顺序储存方式来存储数据。所谓顺序存储,就是数据在内存上的地址同样为连续储存,中间不允许有空(有间隔)。顺序表的优点在于支持随机访问,就是通过下标来访问元素;缺点是插入,删除数据时需要挪动大量元素。共有两种方式来创建顺序表,分别是静态顺序表和动态顺序表。

正文开始:
1.静态顺序表

通过前言,我们可以了解到,顺序表中的数据是连续存放的,所以我们不难想到要用数组来建立顺序表。静态顺序表由一个定长的数组组成。

//静态顺序表
#define MAX 10
typedef int SLDateType;//声明数据类型
typedef struct Seqlist//顺序表
{
   SLDateType arr[MAX];//存放数据的数组
    size_t size;//有效数据个数
}SeqList;

大家可能对typedef int SLDateType;这个语句有点疑问,觉得它多余。其实不然,这样做是为了提高程序的可移植性,如果要改变数据的类型为char只需要改成 typedef char SLDateType,这是比较方便的。

将结构体名重命名为SeqList,是为提高代码的可读性以及简化了复杂的类型声明。

顺序表的基本操作有:(1)顺序表初始化(2)顺序表增容

(3)顺序表尾插(4)顺序表尾删(5)顺序表头插(6)顺序表头删(7)顺序表查找(8)顺序表在指定位置插入x(9)顺序表在指定位置删除(10)顺序表销毁(11)顺序表打印

共有上面这几种基本操作,在本文里我主要用动态顺序表来讲解这些操作,因为动态顺序表相对用的多一些。

2.动态顺序表

动态顺序表就是在堆区上开辟了一个数组来存放数据,如果内存不够,就增容。其余的基本和静态顺序表没区别。

//动态顺序表
typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;//指向了动态开辟的数组空间
	size_t size;//已存数据个数
	size_t capacity; // 总容量
}SeqList;

上文已经说了顺序表的基本操作,我们来逐个击破。

(1)顺序表初始化:

void SeqListInit(SeqList* ps)//初始化
{
	ps->capacity = 0;//容量先置为0
	ps->size = 0;
	ps->a = NULL;//先置为NULL,避免野指针问题
}

(2)顺序表增容

void CheckCapacity(SeqList* ps)//增容
{
	//检查容量是否为0,为0就置新容量为4,不为0就扩2倍
	int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    //调整空间大小
	int* tmp = (int*)realloc(ps->a, newcapacity*sizeof(int));
    //判断是否开辟成功
	if (tmp == NULL)
	{
		printf("realloc fail\n");
		exit(-1);
	}
  //如果开辟成功,对a,capacity赋新值
	ps->a = tmp;
	ps->capacity = newcapacity;
}

(3)顺序表尾插:

void SeqListPushBack(SeqList* ps, SLDateType x)//尾插
{
    //先检查容量
	CheckCapacity(ps);
    //在尾部插入数据x
	ps->a[ps->size] = x;
    //已存数据+1
	ps->size++;

代码跑一波

#include"sxb.h"
void test1()
{
	SeqList sxb;
    //初始化
	SeqListInit(&sxb);
	//尾插1,2,3,4,5
	SeqListPushBack(&sxb, 1);
	SeqListPushBack(&sxb, 2);
	SeqListPushBack(&sxb, 3);
	SeqListPushBack(&sxb, 4);
	SeqListPushBack(&sxb, 5);
    //打印
	SeqListPrint(&sxb);
}
int main()
{
	test1();
	return 0;
}

在这里插入图片描述

(4)顺序表尾删

void SeqListPopBack(SeqList* ps)//尾删
{
	assert(ps->size>0);//断言有效数据是否存在
	ps->size--;//有效数据减少
}

(5)顺序表头插

void SeqListPushFront(SeqList* ps, SLDateType x)//头插
{
	assert(ps);
	CheckCapacity(ps);//检验增容
    //挪动数据
	for (int i = ps->size; i >0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
    //头插
	ps->a[0] = x;
	ps->size++;
}

(6)顺序表头删

void SeqListPopFront(SeqList* ps)//头删
{
	assert(ps->a);
    //覆盖头一个数据
	for (size_t i = 0; i<ps->size; i++)
	{
		ps->a[i] = ps->a[i+1];
	}
    //有效数据减一
	ps->size--;
}

(7)顺序表查找

int SeqListFind(SeqList* ps, SLDateType x)//查找
{
	assert(ps->size > 0);
    //遍历数组,如果找到就返回下标
	for (int i = 0; i < ps->size; i++)
	{
		if (x == ps->a[i])
			return i;
	}
	return -1;
}

(8)顺序表在指定位置插入x

void SeqListInsert(SeqList* ps, size_t pos, SLDateType x)  //指定位置插入
{
	assert(ps->size>0);
	CheckCapacity(ps);
	int end = ps->size;
    //判断pos位置是否正确
	if (pos >= 0 && pos <= ps->size)
	{
        //pos后的位置向后移一位
		for (int i = end; i >pos; i--)
		{
			ps->a[i] = ps->a[i - 1];
		}
		ps->a[pos] = x;
		ps->size++;
	}
	else
		return;
}

(9)顺序表在指定位置删除

void SeqListErase(SeqList* ps, size_t pos)//任意删除
{
	assert(ps->size > 0);
	int begin = pos;
	if (pos >= 0 && pos <= ps->size)
	{
        //pos后的元素向前移一位,覆盖pos位置
		for (int i = begin; i < ps->size; i++)
		{
			ps->a[i] = ps->a[i + 1];
		}
		ps->size--;
	}
}

(10)顺序表销毁

void SeqListDestory(SeqList* ps)//顺序表销毁
{
    //容量置为0,有效数据个数置为0
	ps->capacity = 0;
	ps->size = 0;
    //释放指定的空间
	free(ps->a);
    //将指针置为NULL
	ps->a = NULL;
}

(11)顺序表打印

void SeqListPrint(SeqList* ps)//打印
{
    //遍历数组打印
	for (size_t i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

以上就是本期内容,希望大家有所收获!!!

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

动名词

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值