玩转顺序表——【数据结构】

这篇具有很好参考价值的文章主要介绍了玩转顺序表——【数据结构】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在C语言学习中,我们经常会遇见增删查改等一系列操作,而这些操作全都与线性表关联,没有线性表将会对这些操作完成的十分艰难!那今天就让我们来了解一下顺序表如何增删查改!!!

目录

1.线性表

2.顺序表 

2.1概念及结构

3.对顺序表的实现 

3.1创建动态内容结构体

3.2内存销毁 

 3.3判断是否需要扩容

3.4尾插

3.5头插

3.6 尾删

3.7头删

 3.8 顺序表查找

3.9 顺序表在pos位置插入x

3.10 顺序表删除pos位置的值

顺序表的问题及思考


1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储

玩转顺序表——【数据结构】,数据结构,链表 

2.顺序表 

2.1概念及结构

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

顺序表一般可以分为:

1. 静态顺序表:使用定长数组存储元素:

玩转顺序表——【数据结构】,数据结构,链表

 确定的数组是不能改变的

2.动态顺序表:使用动态开辟的数组存储:

玩转顺序表——【数据结构】,数据结构,链表

通过存放一个结构体指针,使用动态内存开辟malloc函数开辟空间 ,如果空间不够用可以使用realloc函数进行扩容!

3.对顺序表的实现 

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空 间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间 大小,所以下面我们实现动态顺序表。

3.1创建动态内容结构体

typedef int SLDataType;
// 顺序表的动态存储
typedef struct SeqList
{
  SLDataType* array;  // 指向动态开辟的数组
  size_t size ;       // 有效数据个数
  size_t capicity ;   // 容量空间的大小
}SL;

array是动态内存开辟的数组指针,指向开辟的首元素地址。

size是记录存储有效内容的数据个数,方便统计。

capicity是记录容量大小,方便与size进行比较,用来判断是否需要扩容。

我们使用typedef将int重命名为SLDataType,将结构体命名为SL。

 3.2对结构体进行初始化

//第一种方法
void SeqListInit(SL* ps)
{
	ps->a = (SLDateType*)malloc(sizeof(SLDateType) * 4);
	if (ps->a == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	ps->size = 0;
	ps->capacity = 4;
}
//第二种方法
void SeqListInit(SL s)
{
	s.a = NULL;
	s.size = 0;
	s.capacity = 0;
}

第二种方法是直接将结构体的内容传给函数,形参只是实参的一份临时拷贝,形参的改变不会影响实参!!!所以第二种方法是错误的!!! 

当我们使用第一种方法初始化时,我们就可以适当的开辟一点空间,如何使用malloc开辟空间在之前的博客中有所讲解http://t.csdn.cn/038La。如果开辟失败我们就直接退出程序exit(-1)。

3.2内存销毁 

在我们使用动态内存开辟后,一定要及时释放空间并置为NULL,否则会出现内存泄漏等大问题!

void SeqListDestroy(SL* ps)
{
	free(ps->a);
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}

 3.3判断是否需要扩容

在顺序表的增删查改中,我们时不时需要判断存入的数据是否已满,需不需要扩容。所以我们为了方便使用此功能避免程序冗余,我们可以创建此函数用来判断开辟的内存是否需要扩容。

void SLCheckCapacity(SL* ps)
{
	if (ps->size == ps->capacity)
	{
		SLDateType* p = (SLDateType*)realloc(ps->a, sizeof(ps->a) * 2);
		if (*p == NULL)
		{
			perror(realloc);
			exit(-1);
		}
		ps->capacity *= 2;
		ps->a = p;
	}
}

传入结构体指针,判断size与capacity是否相等,如果相等我们就使用realloc函数进行扩容,我们创建新指针指向新创建的空间,开辟比原来大二倍的空间。如果开辟成功我们将更新capacity的值,开辟失败直接退出程序!!!

3.4尾插

void SeqListPushBack(SL* ps, SLDateType x)
{
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

玩转顺序表——【数据结构】,数据结构,链表 先使用函数SLCheckCapacity进行判断是否需要进行扩容,在进行尾部插入即可。

3.5头插

将需要的数据在顺序表的头部进行插入,对于顺序表而言效率会非常低,但是我们也必须将其实现。 

void SeqListPushFront(SL* ps, SLDateType x)
{
	SLCheckCapacity(ps);
	for (int i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i-1];
	}
	ps->a[0] = x;
	ps->size++;
}

玩转顺序表——【数据结构】,数据结构,链表

3.6 尾删

尾删非常的简单,我们只需要将数组往前移动一位,size--即可。我们不必担心数据问题,下次再次使用时只需要将内容覆盖即可。

void SeqListPopBack(SL* ps)
{

	assert(ps->size > 0);
	ps->size--;
}

但是在删除时我们得判断顺序表中内容是否为空,防止数组越界。我们使用assert断言函数进行判断即可。

3.7头删

头删与头插的效率都很低下,这也是顺序表的一个大缺点。基本原理与头插差不多,时间复杂度都为O(n),牵一发而动全身。

void SeqListPopFront(SL* ps)
{
	assert(ps->size > 0);
	for (int i = 0; i < ps->size-1; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

删除时我们必须判断数组是否为空,防止越界。从前向后进行迭代前移进行覆盖,最后将size--即可。玩转顺序表——【数据结构】,数据结构,链表

 3.8 顺序表查找

为了让我们方便查找顺序表中每个内容的具体位置,然后插入想插入的数据。我们创建一个寻找下标的函数。

int SeqListFind(SL* ps, SLDateType x)
{
	assert(ps->size > 0);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
			return i;
	}
	else
		return -1;
}

我们使用暴力查找法,将数组遍历一遍,如果能找到则返回其下标,如果找不到则返回-1结束。 

3.9 顺序表在pos位置插入x

我们使用3.8中的函数,将需要插入位置找到,然后使用此函数将其插入到顺序表中。

void SeqListInsert(SL* ps, int pos, SLDateType x)
{
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		--end;
	}
	ps->a[pos] = x;
	ps->size++;
}

中间插入,前面的数据不需要移动,在pos后的位置要向后移动。

3.10 顺序表删除pos位置的值

void SeqListErase(SL* ps, int pos)
{
	assert(ps->size > 0);
	for (int i = pos - 1; i < ps->size-1; i++)
	{
		ps->a[i] = pos->a[i + 1];
	}
	ps->size--;
}

与插入原理相同,pos后的内容向前一位即可。

顺序表的问题及思考

问题:

1. 中间/头部的插入删除,时间复杂度为O(N)

2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到 200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考:如何解决以上问题呢?下面给出了链表的结构来看看。

我们可以使用链表解决以上问题,下一期我们将走进链表章节。

欲知后事如何,尽情期待下一期!!! 文章来源地址https://www.toymoban.com/news/detail-628801.html

到了这里,关于玩转顺序表——【数据结构】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构2:顺序表和链表

    目录 1.线性表 2.顺序表 2.1概念及结构 2.2接口实现 2.3数据相关面试题 2.4顺序表的问题及思考 3.链表 3.1链表的概念及结构 3.2链表的分类 3.3链表的实现 3.4链表面试题 3.5双向链表的实现 4.顺序表和链表的区别 线性表(linear list)是具有相同特征的数据元素的有限序列。线性表是

    2023年04月17日
    浏览(50)
  • 数据结构(二)----线性表(顺序表,链表)

    目录 1.线性表的概念 2.线性表的基本操作 3.存储线性表的方式 (1)顺序表 •顺序表的概念 •顺序表的实现 静态分配: 动态分配: 顺序表的插入: 顺序表的删除: 顺序表的按位查找: 顺序表的按值查找: 顺序表的特点: (2)单链表 •单链表的实现 不带头结点的单链表

    2024年04月16日
    浏览(57)
  • 《数据结构》实验报告二:顺序表 链表

    1、掌握线性表中元素的 前驱、后续 的概念。 2、掌握顺序表与链表的 建立 、 插入 元素、 删除 表中某元素的算法。 3、对线性表相应算法的 时间复杂度 进行分析。 4、理解顺序表、链表数据结构的特点( 优缺点 )。 说明以下概念 1、线性表:         具有 相同特性 的数

    2024年02月08日
    浏览(43)
  • 常见的数据结构(顺序表、顺序表、链表、栈、队列、二叉树)

    线性表(Linear List)     1.什么是线性表     2.线性表的特点     3.线性表的基本运算 顺序表     1.什么是顺序表     2.时间复杂度: 链表     1.什么是链表     2.单向链表     3. 双向链表     4.ArrayList和LinkedList的使用 栈Stack     1.什么是栈     2.栈的基本方法 队列Queue

    2024年02月13日
    浏览(38)
  • 数据结构顺序表和链表(超详细)

    线性表 ( linear list ) 是 n 个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构, 常见的线性表:顺序表、链表、栈、队列、字符串 ... 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在

    2024年02月13日
    浏览(56)
  • 数据结构:2_顺序表和链表

    线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构, 常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的 ,线性表在物理上

    2024年01月18日
    浏览(55)
  • 数据结构,队列,顺序表队列,链表队列

            队列是一种常见的数据结构,它具有先进先出(First-In-First-Out,FIFO)的特性,类似于排队等候的场景。以下是队列的要点: 1. 定义:队列是一种线性数据结构,由一系列元素组成,可以进行插入和删除操作。插入操作(称为入队)只能在队列的末尾进行,删除操

    2024年02月11日
    浏览(41)
  • 【数据结构初阶】顺序表和链表(1)

    线性表(linear list) 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上

    2024年02月08日
    浏览(242)
  • 数据结构奇妙旅程之顺序表和链表

    ꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶ 个人主页:xiaoxieʕ̯

    2024年02月05日
    浏览(67)
  • 【手撕数据结构】(三)顺序表和链表

    🎗️线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 🎗️线性表在逻辑上是线性结构,也就说是一条连续的直线。但是在物理结构上并不一定是连续的,线性表在物理上存储

    2024年02月05日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包