当前位置: 首页 > news >正文

【硬件-笔试面试题-105】硬件/电子工程师,笔试面试题(知识点:详细讲讲什么是链表和数组)

题目汇总版--链接: 

【硬件-笔试面试题】硬件/电子工程师,笔试面试题汇总版,持续更新学习,加油!!!-CSDN博客

【硬件-笔试面试题-105】硬件/电子工程师,笔试面试题(知识点:详细讲讲什么是链表和数组)

1、题目

详细讲讲什么是链表和数组

2、知识点

链表和数组是两种最基础的数据结构,用于存储和组织一系列相同类型的数据,但它们的底层实现、特性和适用场景有显著区别。以下从定义、结构、操作、区别和适用场景等方面详细讲解:

一、数组(Array)

定义

数组是一种连续存储的线性数据结构,它在内存中占据一块连续的存储空间,所有元素按顺序排列,通过索引(下标)可以直接访问任意元素。

内存结构
  • 数组的元素在内存中是物理地址连续的,例如一个包含 5 个整数的数组int arr[5],在内存中可能占据地址0x1000~0x1014(假设 int 占 4 字节),每个元素的地址间隔固定(等于元素类型大小)。
  • 访问元素时,通过公式地址 = 首地址 + 索引 × 元素大小计算目标元素地址,实现随机访问
核心特性
  1. 固定大小:数组在创建时必须指定长度(静态数组),或动态分配后长度固定(动态数组),无法直接扩容(需手动创建新数组并复制元素)。
  2. 随机访问:通过索引arr[i]访问元素,时间复杂度为O(1)
  3. 连续存储:元素物理地址连续,缓存利用率高(局部性原理)。
基本操作(以 C 语言为例)

c

运行

// 静态数组(编译时确定大小)
int static_arr[5] = {1, 2, 3, 4, 5};// 动态数组(运行时分配大小)
int* dynamic_arr = (int*)malloc(5 * sizeof(int));
for (int i = 0; i < 5; i++) {dynamic_arr[i] = i + 1; // 赋值
}// 访问元素(O(1))
printf("%d\n", static_arr[2]); // 输出3// 插入元素(需移动后续元素,O(n))
// 在index=2处插入6:[1,2,6,3,4,5](需先扩容)// 删除元素(需移动后续元素,O(n))
// 删除index=2的元素:[1,2,4,5](后续元素前移)free(dynamic_arr); // 释放动态数组内存

二、链表(Linked List)

定义

链表是一种非连续存储的线性数据结构,由多个节点(Node)组成,每个节点包含数据域(存储元素)和指针域(存储下一个 / 上一个节点的地址),通过指针将分散的节点串联成逻辑序列。

内存结构
  • 链表的节点在内存中是物理地址分散的,节点之间通过指针关联(逻辑上连续,物理上不连续)。
  • 例如单链表的节点结构:[data | next指针] → [data | next指针] → ...,每个节点的next指针指向后续节点的地址。
核心类型
  1. 单链表:每个节点只有next指针(指向后一个节点),尾节点nextNULL
  2. 双向链表:每个节点有prev(指向前一个)和next(指向后一个)指针,支持双向遍历。
  3. 循环链表:尾节点next指向头节点,形成闭合环,适合循环访问场景。
核心特性
  1. 动态大小:无需预先指定长度,可通过添加 / 删除节点动态调整,内存利用率高。
  2. 顺序访问:只能从表头(或表尾)依次遍历,无法随机访问,访问第i个元素需O(n)时间。
  3. 非连续存储:节点物理地址分散,指针域额外占用内存(如单链表每个节点多 4 字节指针)。
基本操作(C 语言单链表示例)

c

运行

// 定义单链表节点
struct Node {int data;          // 数据域struct Node* next; // 指针域(指向下一个节点)
};// 创建新节点
struct Node* createNode(int data) {struct Node* node = (struct Node*)malloc(sizeof(struct Node));node->data = data;node->next = NULL;return node;
}// 插入节点(头部插入,O(1))
void insertAtHead(struct Node** head, int data) {struct Node* newNode = createNode(data);newNode->next = *head; // 新节点指向原头节点*head = newNode;       // 头指针指向新节点
}// 访问第k个元素(需遍历,O(n))
int getKthElement(struct Node* head, int k) {struct Node* p = head;for (int i = 0; i < k && p != NULL; i++) {p = p->next;}return p ? p->data : -1; // 假设-1表示越界
}// 删除节点(已知前驱节点时O(1))
void deleteNode(struct Node* prev) {struct Node* toDelete = prev->next;prev->next = toDelete->next; // 跳过待删节点free(toDelete);
}

三、数组与链表的核心区别

对比维度数组(Array)链表(Linked List)
存储方式内存连续,物理地址相邻内存分散,通过指针串联逻辑顺序
访问效率随机访问(arr[i]),O(1)顺序访问(遍历),O(n)
插入 / 删除效率需移动大量元素(O(n)),头部 / 中间操作慢仅需调整指针(O(1),已知前驱时),效率高
内存开销无额外开销,但可能浪费空间(预分配)需存储指针,额外开销(如单链表多 4 字节 / 节点)
大小灵活性固定大小,扩容需复制元素(O(n)动态大小,增减节点无需整体调整
缓存友好性连续存储,缓存命中率高分散存储,缓存利用率低

四、适用场景选择

  1. 优先用数组的场景

    • 需要频繁随机访问(如查找、修改指定索引元素),例如数据库索引、矩阵存储。
    • 数据大小固定或可预估,且元素数量少,例如存储用户信息列表、配置参数。
    • 内存开销敏感,不希望额外的指针占用空间。
  2. 优先用链表的场景

    • 需要频繁插入 / 删除(尤其是中间位置),例如实现链表版队列、栈、哈希表冲突解决。
    • 数据大小动态变化,无法预估上限,例如日志记录、实时数据流处理。
    • 无需随机访问,只需顺序遍历,例如实现邻接表(图的存储)、多项式表示。

五、总结

  • 数组是 “连续存储的线性表”,优势是随机访问快、内存紧凑,劣势是大小固定、插入删除效率低。
  • 链表是 “离散存储的线性表”,优势是动态大小、插入删除灵活,劣势是访问效率低、内存开销大。

实际开发中,需根据具体需求(访问方式、增删频率、数据规模)选择合适的数据结构,甚至结合两者的优点(如 Java 的ArrayList用动态数组实现,LinkedList用双向链表实现)。

题目汇总--链接:

【硬件-笔试面试题】硬件/电子工程师,笔试面试题汇总版,持续更新学习,加油!!!-CSDN博客

http://www.dtcms.com/a/394193.html

相关文章:

  • 【获取地址栏的搜索关键字】功能-总结
  • 关于__sync_bool_compare_and_swap的使用及在多核多线程下使用时的思考
  • 【嵌入式简单外设篇】-433MHz 无线遥控模块
  • 计算机视觉(opencv)实战三十——摄像头实时风格迁移,附多种风格转换
  • 【数据分享】《中国农村统计年鉴》(1985-2024年)全pdf和excel
  • 2025年中国研究生数学建模竞赛“华为杯”C题 围岩裂隙精准识别与三维模型重构完整高质量成品 思路 代码 结果分享!全网首发!
  • [Linux]文件与 fd
  • FFmpeg 深入精讲(二)FFmpeg 初级开发
  • 睡眠脑电技术文章大纲
  • 计算机等级考试Python语言程序设计备考•第二练
  • 【Python】面向对象(一)
  • Jetson 设备监控利器:Jtop 使用方式(安装、性能模式、常用页面)
  • 「数据获取」《商洛统计年鉴》(2001-2024)
  • 链表的探索研究
  • 2025年工程项目管理软件全面测评
  • JAVA算法练习题day17
  • Nacos:服务注册和配置中心
  • Linux 命令行快捷键
  • EasyClick JavaScript Number
  • LeetCode:42.将有序数组转化为二叉搜索树
  • 海外代理IP网站有哪些?高并发场景海外代理IP服务支持平台
  • JavaScript数据交互
  • 11.2.5 自定义聊天室
  • 力扣:字母异味词分组
  • Linux视频学习笔记
  • 2014/12 JLPT听力原文 问题四
  • Elasticsearch面试精讲 Day 21:地理位置搜索与空间查询
  • 华为数字化实战指南:从顶层设计到行业落地的系统方法论
  • 外部 Tomcat 部署详细
  • 【回文数猜想】2022-11-9