【数据结构】线性结构——数组、链表、栈和队列

目录

前言

一、数组(Array)

1.1优点

1.2缺点

1.3适用场景

二、链表(Linked List)

2.1优点

2.2缺点

2.3适用场景

三、栈(Stack)

3.1优点

3.2缺点

3.3适用场景

四、队列(Queue)

4.1优点

4.2缺点

4.3适用场景


🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。

💡本文由Filotimo__✍️原创,首发于CSDN📚。

📣如需转载,请事先与我联系以获得授权⚠️。

🎁欢迎大家给我点赞👍、收藏⭐️,并在留言区📝与我互动,这些都是我前进的动力!

🌟我的格言:森林草木都有自己认为对的角度🌟。

前言

数据结构指的是计算机科学中用来组织和存储数据的方式,涉及数据元素之间的关系及其操作定义。数据结构可以分为线性结构和非线性结构。其中,线性结构是指数据元素之间存在一对一的关系,包括数组、链表、栈和队列等。


一、数组(Array)

数组是一种在内存中连续存储多个相同类型元素的数据结构。数组通过索引(通常从0开始)来访问每个元素。

示例代码(以下所有代码都是用C语言编写的)

#include <stdio.h>#define SIZE 5int main() {// 创建一个整数数组int arr[SIZE] = {1, 2, 3, 4, 5};// 访问数组元素printf("Element at index 0: %d\n", arr[0]);  // 输出: 1printf("Element at index 2: %d\n", arr[2]);  // 输出: 3// 修改数组元素arr[1] = 10;printf("Updated array: ");for (int i = 0; i < SIZE; ++i) {printf("%d ", arr[i]);}printf("\n");return 0;
}

运行截图

1.1优点

①        快速访问:由于元素在内存中连续存储,可以通过索引直接访问任何元素,时间复杂度为 O(1)。

②        简单:实现简单直观,是最基础的数据结构之一。

1.2缺点

①        固定大小:数组创建时大小固定,通常无法动态扩展,需要预先确定容量。

②        插入和删除操作慢:在数组中间或开头插入或删除元素需要移动其他元素,时间复杂度为 O(n)。

1.3适用场景

数组适合于元素类型固定、需要频繁访问元素且不需要经常插入或删除元素的场景。

二、链表(Linked List)

链表是一种非连续、非顺序的数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针(或引用)。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表,循环链表等。

示例代码

#include <stdio.h>
#include <stdlib.h>// 定义链表节点结构
typedef struct Node {int data;struct Node* next;
} Node;// 创建一个新的节点
Node* create_node(int data) {Node* new_node = (Node*)malloc(sizeof(Node));  // 分配内存new_node->data = data;new_node->next = NULL;return new_node;
}// 向链表末尾添加节点
void append(Node** head_ref, int new_data) {Node* new_node = create_node(new_data);Node* last = *head_ref;if (*head_ref == NULL) {*head_ref = new_node;return;}while (last->next != NULL) {last = last->next;}last->next = new_node;
}// 打印链表
void print_list(Node* node) {while (node != NULL) {printf("%d -> ", node->data);node = node->next;}printf("NULL\n");
}// 释放链表内存
void free_list(Node* node) {Node* temp;while (node != NULL) {temp = node;node = node->next;free(temp);}
}int main() {Node* head = NULL;// 创建链表append(&head, 1);append(&head, 2);append(&head, 3);append(&head, 4);// 打印链表printf("Linked List: ");print_list(head);// 释放链表free_list(head);return 0;
}

运行截图

2.1优点

①        动态大小:链表可以动态地分配内存空间,不像数组需要预先分配固定大小的空间。

②        插入和删除快速:在链表中插入和删除元素不需要移动其他元素,只需要改变指针指向,时间复杂度为 O(1)。

2.2缺点

①        随机访问慢:链表的元素不连续存储,访问特定位置的元素需要从头开始遍历,时间复杂度为 O(n)。

②        额外空间:每个节点除了存储数据外,还需存储指针,占用较多的内存空间。

2.3适用场景

链表适合于需要频繁插入和删除操作、内存空间不确定或者不需要随机访问元素的场景。

三、栈(Stack)

栈是一种特殊的线性表,具有后进先出(LIFO,Last In First Out)的特点,只允许在一端进行插入和删除操作。这一端被称为栈顶,另一端称为栈底。

示例代码

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100  // 栈的最大容量// 定义栈结构体
typedef struct {int items[MAX_SIZE];int top;  // 栈顶指针
} Stack;// 初始化栈
void init(Stack* stack) {stack->top = -1;  // 栈顶指针初始化为-1,表示栈为空
}// 判断栈是否为空
int is_empty(Stack* stack) {return stack->top == -1;
}// 判断栈是否已满
int is_full(Stack* stack) {return stack->top == MAX_SIZE - 1;
}// 入栈操作
void push(Stack* stack, int item) {if (is_full(stack)) {printf("Stack overflow\n");return;}stack->items[++stack->top] = item;  // 栈顶指针先加一,然后添加元素
}// 出栈操作
int pop(Stack* stack) {if (is_empty(stack)) {printf("Stack underflow\n");return -1;  // 返回-1表示出栈失败}return stack->items[stack->top--];  // 返回栈顶元素,并将栈顶指针减一
}// 查看栈顶元素
int peek(Stack* stack) {if (is_empty(stack)) {printf("Stack is empty\n");return -1;  // 返回-1表示栈为空}return stack->items[stack->top];  // 仅返回栈顶元素,不改变栈的状态
}// 获取栈的大小
int size(Stack* stack) {return stack->top + 1;
}int main() {Stack stack;init(&stack);  // 初始化栈push(&stack, 10);push(&stack, 20);push(&stack, 30);printf("Top element is %d\n", peek(&stack));  // 输出: 30printf("Stack size is %d\n", size(&stack));   // 输出: 3printf("Popped element is %d\n", pop(&stack));  // 输出: 30printf("Popped element is %d\n", pop(&stack));  // 输出: 20printf("Top element is %d\n", peek(&stack));  // 输出: 10return 0;
}

运行截图

3.1优点

①        操作简单:只允许在栈顶进行插入和删除操作,实现简单直观。

②        内存管理方便:栈的内存管理由系统自动处理,无需程序员手动管理。


3.2缺点

①        容量限制:栈的大小受限于系统内存的大小,可能会造成栈溢出。

②        不支持随机访问:由于只能操作栈顶元素,无法直接访问栈中间的元素。


3.3适用场景

①        递归算法(如深度优先搜索)

②        表达式求值(如逆波兰表达式)

③        括号匹配(如编译器的语法分析)

④        历史记录(如浏览器前进后退功能)

⑤        撤销操作(如文本编辑器的撤销功能)

四、队列(Queue)

队列是一种具有先进先出(FIFO,First In First Out)特性的数据结构,允许在一端插入(enqueue)元素,另一端删除(dequeue)元素。通常用于需要按顺序处理数据的场景。

示例代码

#include <stdio.h>
#include <stdlib.h>#define MAX_SIZE 100  // 队列的最大容量// 定义队列结构体
typedef struct {int items[MAX_SIZE];int front;  // 队头指针int rear;   // 队尾指针int size;   // 队列当前元素个数
} Queue;// 初始化队列
void init(Queue* queue) {queue->front = 0;queue->rear = -1;queue->size = 0;
}// 判断队列是否为空
int is_empty(Queue* queue) {return queue->size == 0;
}// 判断队列是否已满
int is_full(Queue* queue) {return queue->size == MAX_SIZE;
}// 入队操作
void enqueue(Queue* queue, int item) {if (is_full(queue)) {printf("Queue overflow\n");return;}queue->rear = (queue->rear + 1) % MAX_SIZE;  // 环形队列实现queue->items[queue->rear] = item;queue->size++;
}// 出队操作
int dequeue(Queue* queue) {if (is_empty(queue)) {printf("Queue underflow\n");return -1;  // 返回-1表示出队失败}int dequeued_item = queue->items[queue->front];queue->front = (queue->front + 1) % MAX_SIZE;  // 环形队列实现queue->size--;return dequeued_item;
}// 查看队头元素
int peek(Queue* queue) {if (is_empty(queue)) {printf("Queue is empty\n");return -1;  // 返回-1表示队列为空}return queue->items[queue->front];
}// 获取队列的大小
int size(Queue* queue) {return queue->size;
}int main() {Queue queue;init(&queue);  // 初始化队列enqueue(&queue, 10);enqueue(&queue, 20);enqueue(&queue, 30);printf("Front element is %d\n", peek(&queue));  // 输出: 10printf("Queue size is %d\n", size(&queue));     // 输出: 3printf("Dequeued element is %d\n", dequeue(&queue));  // 输出: 10printf("Dequeued element is %d\n", dequeue(&queue));  // 输出: 20printf("Front element is %d\n", peek(&queue));  // 输出: 30return 0;
}

运行截图

4.1优点

①        按序处理:队列确保元素按照入队的顺序处理,符合先进先出的逻辑。

②        操作简单:队列仅支持在队尾插入和队头删除操作,设计和实现都较为简单。

③        资源管理:队列的大小可以动态增长,灵活适应不同数据量的需求。

4.2缺点

①        固定容量:队列的大小通常是固定的,可能会导致队列满时无法继续入队(队列溢出)。

②        不支持随机访问:只能访问队头元素,不能直接访问队列中间的元素。

4.3适用场景

①        任务调度:用于任务按顺序执行,例如操作系统中的进程调度。

②        消息传递:用于实现异步消息传递机制,例如消息队列中间件。

③        广度优先搜索:在图的遍历中,广度优先搜索算法需要使用队列来管理遍历的节点顺序。

④        缓冲:用于平衡生产者和消费者之间的速度差异,例如生产者消费者模型中的缓冲区。

⑤        网络数据包处理:在网络数据传输中,使用队列来管理接收到的数据包。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/48048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

广义可加模型和光滑曲线拟合的R代码

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

ABAQUS细观混凝土周期性边界(PBC)表征体元(REV)界面层(ITZ)及砂浆塑性损伤(CDP)模拟

混凝土的细观结构决定着其宏观破坏行为&#xff0c;对混凝土在结构尺度上采用细观模型将导致巨大的计算量而难以实现&#xff0c;表征体元&#xff08;‌REV&#xff09;‌方法可选取一定的平均范围来描述混凝土的性质和行为&#xff0c;这对于理解和模拟混凝土的损伤机理至关重…

测试用例的设计方法

等价类 等价类概念&#xff1a;在所有测试的数据中&#xff0c;具有某种共同特征的数据子集 边界值 边界值分析是对程序输入或输出的边界值进行测试的一种黑盒测试方法 边界值是作为等价类的补充&#xff0c;其主要区别是&#xff1a; 边界值测试设计不是从某一个等价类中…

15. 【C++】详解搜索二叉树 | KV模型

目录 1.定义 初始化 插入 查找 删除 完整代码 2.运用 K 模型和 KV 模型详解 K 模型 KV 模型 代码解释 为了更好地理解 map 和 set 的特性&#xff0c;和后面讲解查找效率极高的平衡搜索二叉树&#xff0c;和红黑树去实现模拟&#xff0c;所以决定在这里对搜索二叉树…

Google资深工程师深度讲解Go语言-课程笔记

课程目录&#xff1a; 第1章 课程介绍 欢迎大家来到深度讲解Go语言的课堂。本课程将从基本语法讲起&#xff0c;逐渐深入&#xff0c;帮助同学深度理解Go语言面向接口&#xff0c;函数式编程&#xff0c;错误处理&#xff0c;测试&#xff0c;并行计算等元素&#xff0c;并带…

(vue)Vue读取public中的json文件,打包后只需更改包文件

(vue)Vue读取public中的json文件,打包后只需更改包文件 背景&#xff1a;增加账号需求。原本是在页面&#xff0c;每次都需技术人员添加再打包部署&#xff0c;现在放到json里&#xff0c;以后直接服务器改json就行。 旧版&#xff1a; let userArr [{username:aaa,password:…

VLAN 划分案例详解

vlan 的应用在网络项目中是非常广泛的&#xff0c;基本上大部分的项目都需要划分 vlan&#xff0c;这里从基础的 vlan 的知识开始&#xff0c;了解 vlan 的划分原理。 为什么需要 vlan&#xff1a; 1、什么是 VLAN&#xff1f; VLAN&#xff08;Virtual LAN&#xff09;&…

Python数据分析实战:利用ARIMA模型洞察股市规律

在股市中&#xff0c;数据的波动与变化风云莫测&#xff0c;难以捉摸。然而&#xff0c;借助科学的分析方法和工具&#xff0c;我们或许能够找到一些数据规律。今天&#xff0c;我们聊聊如何使用Python编程语言&#xff0c;结合ARIMA模型来洞察股市的变幻&#xff0c;为我们的投…

【TCP通信】

7.18学习记录 NetAssist.exeTCP/IP协议准备工作做好之后开始创建方案 通信架构设备管理接收事件发送事件心跳管理响应配置 VM4.0二次开发 NetAssist.exe 网络协议调试助手文件&#xff0c;支持UDP和TCP协议。只需要输入主机的地址和端口就能获取数据解析。要用到的协议是 TCP/…

wps office 2019 Pro Plus 集成序列号Vba安装版教程

前言 wps office 2019专业增强版含无云版是一款非常方便的办公软件&#xff0c;我们在日常的工作中总会碰到需要使用WPS的时候&#xff0c;它能为我们提供更好的文档编写帮助我们更好的去阅读PDF等多种格式的文档&#xff0c;使用起来非常的快捷方便。使用某银行专业增强版制作…

生活中生智慧

【 圣人多过 小人无过 】 觉得自己做得不够才能做得更好&#xff0c;互相成全&#xff1b;反求诸己是致良知的第一步&#xff1b;有苦难才能超越自己&#xff0c;开胸怀和智慧&#xff1b;不浪费任何一次困苦&#xff0c;危机中寻找智慧&#xff0c;成长自己。 把困苦当作当下…

Linux——awk操作符

[rootlocalhost ~] # awk BEGIN{x2;y3;print x**y,x^y,x*y,x/y,xy,x-y,x%y} 8 8 6 0 .666667 5 -1 2 赋值运算符 条件运算符 awk 中的条件运算符只有一个&#xff0c;其语法如下&#xff1a; expression?value1:value2 这是一个三目运算符&#xff0c;当表达式 expre…

MySQL索引特性(上)

目录 索引的重要 案例 认识磁盘 MySQL与存储 先来研究一下磁盘 扇区 定位扇区 结论 磁盘随机访问与连续访问 MySQL与磁盘交互基本单位 建立共识 索引的理解 建立测试表 插入多条记录 局部性原理 所有的MySQL的操作(增删查改)全部都是在MySQL当中的内存中进行的&am…

【删除链表的倒数第N个节点】python刷题记录

目录 哑结点 为什么设置哑节点&#xff1f; 方法1&#xff08;先遍历统计长度&#xff0c;再查找具体位置&#xff09;&#xff1a; 方法2&#xff08;双指针&#xff09;&#xff1a; 链表基本用法 哑结点 在链表前面添加哑节点&#xff0c;指向头节点 为什么设置哑节点…

系统架构师考点--统一建模语言UML

大家好。今天我来总结一下面向对象的第二个考点–统一建模语言UML。 UML(统一建模语言)是一种可视化的建模语言&#xff0c;而非程序设计语言&#xff0c;支持从需求分析开始的软件开发的全过程。UML的结构包括构造块、规则和公共机制三个部分。其中考点主要集中在构造块部分&…

一建备考,五步形成闭环学习!

一建备考从7月份到考前是大部分人焦虑的时候&#xff0c;因为基础阶段结束&#xff0c;开始成套做真题了&#xff0c;第一遍做真题很多人分数都不太理想&#xff0c;很多同学直接失去信心&#xff0c;开始emo&#xff0c;这都是只听课不做题的结果。 现在很多同学都是这种情况…

ABAP group by 语句学习

第一个案例&#xff1a;原文链接&#xff1a;https://blog.csdn.net/lmf496891416/article/details/111317377 第一步&#xff1a;定义结构&#xff0c;此处定义了三个字段 key1 ,key2 ,col ,然后定义表 itab 参照结构 struct TYPES: BEGIN OF ty_employee,name TYPE char30,…

ASUS/华硕幻13 2022 GV301R系列 原厂win11系统 工厂文件 带F12 ASUS Recovery恢复

华硕工厂文件恢复系统 &#xff0c;安装结束后带隐藏分区&#xff0c;一键恢复&#xff0c;以及机器所有驱动软件。 系统版本&#xff1a;windows11 原厂系统下载网址&#xff1a;http://www.bioxt.cn 需准备一个20G以上u盘进行恢复 请注意&#xff1a;仅支持以上型号专用…

平凯星辰黄东旭出席 2024 全球数字经济大会 · 开放原子开源数据库生态论坛

7 月 5 日&#xff0c;以“开源生态筑基础&#xff0c;数字经济铸未来”为主题的 2024 全球数字经济大会——开放原子开源数据库生态论坛在北京成功举办。平凯星辰&#xff08;北京&#xff09;科技有限公司联合创始人黄东旭发表了题为《TiDB 助力金融行业关键业务系统实践》的…

校验el-table中表单项

需求&#xff1a; 表格中每一行都有几个必填项&#xff0c;如用户提交时有未填的选项&#xff0c;将该选项标红且给出提示&#xff0c;类似el-form 的那种校验 el-table本身并没有校验的方法&#xff0c;而且每一行的输入框也是通过插槽来实现的&#xff0c;因此我们要自己跟…