顺序表(数据结构)---排队啦!(一)

简介: 顺序表(数据结构)---排队啦!(一)

前言:


 这节我们来学习和实现线性结构中最简单的顺序表,由于博主使用C语言实现的,所以读者要对C语言的结构体、指针、内存管理这三部分知识做到理解并掌握。看代码能理解,能看懂,相信自己的实力!


1.线性表的性质


 数据在内存中存储有两种结构、分别是逻辑结构和物理结构。顺序表就是逻辑结构中的线性结构+物理结构中的顺序结构。


 线性结构的性质:线性意味着内存中的数据之间的关系呈现一条线状。


 顺序结构的要求:顺序结构要求数据之间是有序的,数据元素与数据元素是紧挨着的,就像排队一样。


 顺序表的本质:看完线性结构和顺序结构后,脑海里有没有涌现一股灵感呢?是的,顺序表的本质就是一个数组。这个数组和普通的数组不太一样,我们普通的数组可以进行以下这样的操作:

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    arr[0] = 1;
    arr[5] = 10;
    arr[9] = 20;
    return 0;
}

 假如我们要把3个整型值放到一个数组里面,普通数组可以将这3个整型值放到该数组中的任意位置;比如这个数组的第一个元素、第六个元素、最后一个元素分别被赋值了1、10、20。然而,顺序表要存放这3个值,只能按顺序存放在下标为0、1、2的元素位置上。


2.静态数组or动态数组


2.1静态数组

 静态数组是我们一开始就确定好数组的大小,在运行时不能改变数组存储多少。所以这里就有个问题:


当我们在用静态数组开辟空间的时候,给了100个元素空间,但实际情况需要存101个元素,但存不了了,数组已经满了

所以我决定给个大一点的数组,创建一个能存放1000个元素的数组,但实际情况只需要存200个元素,造成了不必要的浪费。

 总结:静态数组的缺陷就是,数组空间开辟小了不够用,开辟大了用不完。


2.2动态数组

 所以我们选择能根据具体的存储情况,开辟大小适合的数组,动态数组可以实现。


 动态开辟的空间是在堆区上开辟的,会使用到realloc函数开辟堆区上的空间,我们在这里描述一下这个函数的功能吧。realloc本意是追增空间,malloc才是一个纯正实现开辟空间的函数,但realloc的功能更强大。


realloc的功能

情形:

功能:

接收地址的指针为空指针

相当于malloc开辟堆区空间

指针指向的堆空间够追加

原地扩容,不需要换内存位置

指针指向的堆空间不够追加

将原先内存空间数据搬家到扩容后的内存上

   相信没学过内存管理的同学一脸茫然,头顶打着问号,看图理解:


接收地址的指针未空指针的情况:


指针指向的堆空间够追加的情况:


指针指向的堆空间不够追加的情况:


 就这样,一开始给数组小一点的空间,空间不够了,在realloc的帮助下增容就实现动态数组了。一般每次增容,新容量都是原容量的2倍。


3.结构体的创建


 进度有点慢了,我们直接看代码:


 1.静态顺序表:



 将数组元素个数用宏(N)表示,此后凡是需要改变数组个数,不用一个一个改,只用改N就可以全部替换了;将顺序表的数组元素类型改名为SLDataType也是同理;


 2.动态顺序表



 其实动态数组的创建的一些情况还是和静态数组一样的,比如把struct SeqList的名字改成SL,元素类型用SLDataType。主要不同的点是用指针管理开辟的数组空间,多一个capacity变量表示数组的最大容量。


 补充:分模块写的重要性



test.c文件是用来测试SeqList的功能的一个文件。

SeqList.h用来声明接口函数的,还有一些宏,程序用得到的库函数头文件等。

SeqList.c是用来实现接口函数的。

 补充:使用宏#pragma once可以防止头文件被多次包含;我们引头文件的时候,编译器会把头文件里的内容复制一份放到我们的程序当中,如果我们多次引用,就会有很多重复的代码,这个宏就够很好的防止头文件被多次引用。


 好的,前提都说完了,进入正题。学习思想,实现接口函数。

相关文章
|
2天前
|
存储 C语言 C++
数据结构基础详解(C语言) 顺序表:顺序表静态分配和动态分配增删改查基本操作的基本介绍及c语言代码实现
本文介绍了顺序表的定义及其在C/C++中的实现方法。顺序表通过连续存储空间实现线性表,使逻辑上相邻的元素在物理位置上也相邻。文章详细描述了静态分配与动态分配两种方式下的顺序表定义、初始化、插入、删除、查找等基本操作,并提供了具体代码示例。静态分配方式下顺序表的长度固定,而动态分配则可根据需求调整大小。此外,还总结了顺序表的优点,如随机访问效率高、存储密度大,以及缺点,如扩展不便和插入删除操作成本高等特点。
|
2天前
|
存储 算法 C语言
C语言手撕数据结构代码_顺序表_静态存储_动态存储
本文介绍了基于静态和动态存储的顺序表操作实现,涵盖创建、删除、插入、合并、求交集与差集、逆置及循环移动等常见操作。通过详细的C语言代码示例,展示了如何高效地处理顺序表数据结构的各种问题。
|
26天前
|
存储 算法
【数据结构与算法】顺序表
【数据结构与算法】顺序表
12 0
【数据结构与算法】顺序表
|
24天前
|
存储 算法
【初阶数据结构篇】顺序表和链表算法题
此题可以先找到中间节点,然后把后半部分逆置,最近前后两部分一一比对,如果节点的值全部相同,则即为回文。
|
24天前
|
存储 测试技术
【初阶数据结构篇】顺序表的实现(赋源码)
线性表(linearlist)是n个具有相同特性的数据元素的有限序列。
|
29天前
|
存储 编译器
【数据结构】顺序表(长期维护)
【数据结构】顺序表(长期维护)
|
29天前
|
存储 缓存
【数据结构】——顺序表与链表
【数据结构】——顺序表与链表
|
2天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
|
3天前
|
Java
【数据结构】栈和队列的深度探索,从实现到应用详解
本文介绍了栈和队列这两种数据结构。栈是一种后进先出(LIFO)的数据结构,元素只能从栈顶进行插入和删除。栈的基本操作包括压栈、出栈、获取栈顶元素、判断是否为空及获取栈的大小。栈可以通过数组或链表实现,并可用于将递归转化为循环。队列则是一种先进先出(FIFO)的数据结构,元素只能从队尾插入,从队首移除。队列的基本操作包括入队、出队、获取队首元素、判断是否为空及获取队列大小。队列可通过双向链表或数组实现。此外,双端队列(Deque)支持两端插入和删除元素,提供了更丰富的操作。
10 0
【数据结构】栈和队列的深度探索,从实现到应用详解
|
26天前
栈的几个经典应用,真的绝了
文章总结了栈的几个经典应用场景,包括使用两个栈来实现队列的功能以及利用栈进行对称匹配,并通过LeetCode上的题目示例展示了栈在实际问题中的应用。
栈的几个经典应用,真的绝了