八种数据结构简介

目录

1.1 数据结构概述

1.2 数据结构的分类

1.2.1 逻辑结构

1)集合

2)线性结构

3)树形结构

4)图形结构

1.2.2 物理结构

1)顺序存储

2)链式存储

3)散列存储

4)索引存储

1.3 数据结构的实现

1.2.1 数组

1.2.2 链表

1.2.3 栈

1.2.4 队列

1.2.5 树

1.2.6 堆

1.2.7 散列表

1.2.8 图


1.1 数据结构概述


数据结构是计算机存储、组织数据的方式;通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率,这也是判断数据结构优良的两个维度。数据结构的优良将直接影响着我们程序的性能;

通常情况下,这两个维度是相悖的,即:更高的运行效率往往存储效率较低,更高的存储效率往往运行效率较低。

1.2 数据结构的分类


数据结构的世界非常丰富多彩,在学习之前我们必须先给它归类。数据结构一般分为逻辑结构和物理结构这两大总类,在两大总类下还可以细分出其他分类。

逻辑结构:数据元素之间的逻辑联系(关注数据间的关系)
物理结构:数据元素的存放形式(关注数据的存储方式)


1.2.1 逻辑结构


逻辑结构是指数据对象中数据元素之间相互关系(逻辑关系),即从逻辑关系上描述数据。它与数据的存储无关,是独立于计算机存储器的。根据数据元素之间关系的不同特征,通常有下列4类基本结构,复杂程度依次递进。

1)集合

集合:数据结构中的元素之间除了“同属一个集合” 的相互关系外,别无其他关系;

2)线性结构

线性结构:数据结构中的元素存在一对一的相互关系;

3)树形结构

树形结构:数据结构中的元素存在一对多的相互关系;

4)图形结构

图形结构:数据结构中的元素存在多对多的相互关系;

1.2.2 物理结构


数据的物理结构是指数据的逻辑结构在计算机中的存储方式(就是数据存储在磁盘中的方式)。是数据结构在计算机中的实现方法,包括数据元素的表示和元素之间的关系。

物理结构一般有四种:顺序存储,链式存储,散列,索引。

1)顺序存储


顺序存储结构是把数据元素放在地址连续的存储单元中,程序设计中使用数组类型来实现。(逻辑相邻物理相邻)

2)链式存储

把数据元素存储在任意的存储单元里,这组存储单元可以是连续的也可以是不连续的,程序设计中使用指针类型来实现。(逻辑相邻物理不一定相邻),程序设计中使用链表来实现。

3)散列存储

散列存储结构通过计算元素的散列值直接确定数据元素的物理位置,设计时需处理哈希冲突(如链地址法、开放寻定法)。

数据元素在存储空间中呈分散分布,物理相邻性与逻辑顺序无直接关联,程序设计常通过哈希表结构实现。(逻辑无相邻性,物理位置由哈希函数决定)

4)索引存储

索引存储结构将数据元素存放在任意存储单元中,同时维护一个独立的索引表(如B树、倒排索引)。访问时先查询索引表获取地址再定位数据,逻辑顺序由索引表维护而非物理位置决定。

程序设计可通过键值对数据库、文件系统目录等实现。(逻辑关系由索引表维护,物理位置可任意分布)

1.3 数据结构的实现

数据结构可视化网站:Data Structure Visualization

常见的数据结构实现有:数组(Array)、栈(Stack)、队列(Queue)、链表(Linked List)、树(Tree)、图(Graph)、堆(Heap)、散列表(Hash)等; 

1.2.1 数组
  • 数组(Array):数组是有序元素的序列,在内存中的分配是连续的,数组会为存储的元素都分配一个下标(索引),此下标是一个自增连续的,访问数组中的元素通过下标进行访问;数组下标从0开始访问;
  • 数组的优点是:查询速度快;
  • 数组的缺点是:增加、删除慢;由于数组为每个元素都分配了索引且索引是自增连续的,因此一但删除或者新增了某个元素时需要调整后面的所有元素的索引;

新增一个元素40到3索引下标位置:

删除2索引元素: 

总结:数组查询快,增删慢,适用于频繁查询,增删较少的情况;

1.2.2 链表

  • 链表(Linked List):链表是由一系列节点Node(也可称元素)组成,数据元素的逻辑顺序是通过链表的指针地址实现,通常情况下,每个节点包含两个部分,一个用于存储元素的数据,名叫数据域,另一个则指向下一个相邻节点地址的指针,名叫指针域;根据链表的指向不同可分为单向链表、双向链表、循环链表等;我们本章介绍的是单向链表,也是所有链表中最常见、最简单的链表;


链表的节点(Node):

完整的链表:

  • 链表的优点:新增节点、删除节点快;

在链表中新增一个元素:

 在单向链表中,新增一个元素最多只会影响上一个节点,比在数组中的新增效率要高的多;

在链表中删除一个元素: 

  • 链表的缺点:
    • 1)查询速度慢,查询从头部开始一直查询到尾部,如果元素刚好是在最尾部那么查询效率势必非常低;
    • 2)链表相对于数组多了一个指针域的开销,内存相对占用会比较大;

总结:数据量较小,需要频繁增加,删除操作的场景,查询操作相对较少;

1.2.3 栈

  • 栈(Stack):是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出从栈顶放入元素的操作叫入栈(压栈),取出元素叫出栈(弹栈)。


入栈操作:

出栈操作:

栈的特点:先进后出,Java中的栈内存就是一个栈的数据结构,先调用的方法要等到后调用的方法结束才会弹栈(出栈);

Tips:

1)数组实现的栈:https://www.cs.usfca.edu/~galles/visualization/StackArray.html
2)链表实现的栈:https://www.cs.usfca.edu/~galles/visualization/StackLL.html

1.2.4 队列
  • 队列(Queue):队列与栈一样,也是一种线性表,其限制是仅允许在队列的一端进行插入,而在表的另一端进行删除。队列的特点是先进先出,从一端放入元素的操作称为入队,取出元素为出队;

队列的特点:先进先出; 

Tips:

1)数组实现的队列:https://www.cs.usfca.edu/~galles/visualization/QueueArray.html
2)链表实现的队列:https://www.cs.usfca.edu/~galles/visualization/QueueLL.html

1.2.5 树


树是一种数据结构,它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做 “树” 是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

1)每个节点有0个或多个子节点;
2)没有父节点的节点称为根节点;
3)每一个非根节点有且只有一个父节点;
4)每个子节点可以分为多个不相交的子树;
5)右子树永远比左子树大,读取顺序从左到右;


树的分类有非常多种,平衡二叉树(AVL)、红黑树RBL(R-B Tree)、B树(B-Tree)、B+树(B+Tree)等,但最早都是由二叉树演变过去的;

二叉树的特点:每个结点最多有两颗子树

Tips:

1)二叉树:https://www.cs.usfca.edu/~galles/visualization/BST.html
2)平衡二叉树:https://www.cs.usfca.edu/~galles/visualization/AVLtree.html
3)红黑树:https://www.cs.usfca.edu/~galles/visualization/RedBlack.html
4)B-Tree:https://www.cs.usfca.edu/~galles/visualization/BTree.html
5)B+Tree:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

1.2.6 堆


堆(Heap):堆可以看做是一颗用数组实现的二叉树,所以它没有使用父指针或者子指针。堆根据“堆属性”来排序,“堆属性”决定了树中节点的位置。


堆分为两种:大根堆和小根堆,两者的差别在于节点的排序方式。

  1. 大根堆:父节点的值比每一个子节点的值都要大。
  2. 小根堆:父节点的值比每一个子节点的值都要小。

这就是所谓的“堆属性”,并且这个属性对堆中的每一个节点都成立。

根据这一属性,那么最大堆总是将其中的最大值存放在树的根节点。而对于最小堆,根节点中的元素总是树中的最小值。堆属性非常有用,因为堆常常被当做优先队列使用,因为可以快速地访问到“最重要”的元素。

Tips:堆的根节点中存放的是最大(大根堆)或者最小(小根堆)元素,但是其他节点的排序顺序是未知的。例如,在一个最大堆中,最大的那一个元素总是位于 index 0 的位置,但是最小的元素则未必是最后一个元素。唯一能够保证的是最小的元素是一个叶节点,但是不确定是哪一个。

大小根堆数据结构图:

因为堆有序的特点,因此我们可以使用堆的属性来做数组中的排序,简称为堆排序(Heap Sort)。

常见的堆有二叉堆、斐波那契堆等。

小根堆:Heap Visualization

1.2.7 散列表

  • 散列表(Hash),也叫哈希表,是根据键和值 (key和value) 直接进行访问的数据结构,通过key和value来映射到散列表中的一个位置,这样就可以很快找到集合中的对应元素。它利用数组支持按照下标访问的特性,所以散列表其实是数组的一种扩展,由数组演化而来。


散列表首先需要根据key来计算数据存储的位置,也就是数组索引的下标;

  • HashValue=hash(key)


散列表就是把Key通过一个固定的算法函数既所谓的哈希函数转换成一个整型数字(hash值),然后就将hash值对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里,这种存储空间可以充分利用数组的查找优势来查找元素,所以查找的速度很快。

在散列表中,左边是个数组,数组的每个成员包括一个指针,指向一个链表的头,当然这个链表可能为空,也可能元素很多。我们根据元素的一些特征把元素分配到不同的链表中去,也是根据这些特征,找到正确的链表,再从链表中找出这个元素。 

散列表:Open Hashing Visualization

1.2.8 图

  • 图(Graph):图是一系列顶点(元素)的集合,这些顶点通过一系列边连接起来组成图这种数据结构。顶点用圆圈表示,边就是这些圆圈之间的连线。顶点之间通过边连接。


图分为有向图和无向图:

  1. 有向图:边不仅连接两个顶点,并且具有方向;
  2. 无向图:边仅仅连接两个顶点,没有其他含义;

例如,我们可以把图这种数据结构看做是一张地图:

地图中的城市我们看做是顶点,高铁线路看做是边;很显然,我们的地图是一种无向图,以长沙到上海为例,经过的城市有长沙、南昌、杭州、上海等地;那么从上海也可以按照原有的路线进行返回;

实现了图这种数据结构之后我们可以在此数据结构上做一些复杂的算法计算,如广度优先搜索算法、深度优先搜索算法等;

  • 广度搜索:搜索到一个顶点时,先将此顶点的所有子顶点全部搜索完毕,再进行下一个子顶点的子顶点搜索;

例如上图:以武汉为例进行广度搜索,

  • 深度搜索:搜索到一个顶点时,先将此顶点某个子顶点搜索到底部(子顶点的子顶点的子顶点…),然后回到上一级,继续搜索第二个子顶点一直搜索到底部;

例如上图:以武汉为例进行深度搜索, 

Tips:

  • 1)广度搜索:Breadth-First Search
  • 2)深度搜索:Depth-First Search Visualization

图是一种比较复杂的数据结构,在存储数据上有着比较复杂和高效的算法,分别有邻接矩阵 、邻接表、十字链表、邻接多重表、边集数组等存储结构。我们本次了解到这里即可; 

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

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

相关文章

破壁虚实的情感科技革命:元晟定义AI陪伴机器人个性化新纪元

在人工智能席卷全球的浪潮中,广东中山一家名为元晟传媒科技的企业正悄然改写情感陪伴产业的游戏规则。作为广东元伴智能科技(下称“元伴智能”)的战略级下属机构,中山元晟传媒科技凭借独特的“技术场景流量”三角模型,…

leetcode_455 分饼干

1. 题意 给一堆饼干,和一群小朋友。饼干有大小,小朋友有胃口值;小朋友不吃比自己胃口小的饼干,问这些饼干能满足多少小朋友食用。 2. 题解 排序贪心 优先用小饼干满足胃口小的小朋友,这样大饼干就能留给胃口大的小朋…

使用 C# 源生成器(Source Generators)进行高效开发:增强 Blazor 及其他功能

.NET 中源生成器的引入彻底改变了我们的开发方式,它消除了动态逻辑,并在编译时生成静态代码。这不仅提高了应用程序的性能,还提升了开发人员的生产力和代码质量。 如果您正在使用Blazor(WebAssembly 或服务器)或构建需…

word如何插入高清晰的matlab绘图

emf矢量图 在matlab中画好的图另存为emf格式,保存到本地,然后在word中选择插图图片,注意不要复制粘贴。 亲测好用!

解锁 ChatGPT 超能力:全新「记忆」功能深度解析!

点击下方“JavaEdge”,选择“设为星标” 第一时间关注技术干货! 免责声明~ 任何文章不要过度深思! 万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案…

低压电涌保护:构筑电气设备的安全防线

在现代电力系统中,低压电涌保护扮演着至关重要的角色。雷电和电力系统中的瞬态过电压,是威胁电气设备安全运行的潜在风险。低压电涌保护器(SPD)作为一种专门设计的防护装置,能够有效地抑制这些电涌,确保电气…

GitLab多人协作MR流程规范模版(merge)

以下是一个适用于 GitLab 多人协作的 MR 流程规范模板,涵盖分支策略、MR 创建流程、冲突处理、审查要求和 CI/CD 设置。可以直接复制到团队 Wiki 或文档中使用。 📘 一、分支策略 main ← 线上生产分支,仅从 release 合并 dev …

分布式系统全链路监控之一:分布式全链路监控基础概念和OpenTelemetry

文章目录 前言什么是OpenTelemetry核心概念可观测性可靠性和指标理解分布式链路追踪日志跨度链路 上下文传播上下文传播 信号日志OTel日志在 OTel Collector 中的 OTel日志应用程序的OTel日志 结构化、非结构化和半结构化日志结构化日志非结构化日志半结构化日志 OTel日志组件 …

C# 正方形外接圆的面积(Area of a Circumscribed Circle of a Square)

给定正方形的边长,求其外接圆的面积。 示例: 输入:a 6 输出:外接圆的面积为:56.55 输入:a 4 输出:外接圆的面积为:25.13 正方形的四条边相等,四个角均为90度。圆…

ROS学习话题通信之Python实现

与上一篇C实现同理 下面给出相关的Python实现代码 关于py文件的 talker:(demo01_talker_str_py import rclpy from rclpy.node import Node from std_msgs.msg import Stringclass Talker(Node):def __init__(self):super().__init__("talker_node_py")…

Spring MVC 入门案例:从代码到原理的深度剖析

一、引言 Spring MVC 是一种基于 Java 的实现了 MVC 设计模式的请求驱动类型的轻量级 Web 框架,它为开发 Web 应用提供了强大而灵活的解决方案。本文将通过一个简单的 Spring MVC 入门案例,详细介绍其工作流程,帮助读者深入理解 Spring MVC …

零基础学前端-传统前端开发(第四期-JS基础-数组)

注:JS文章流程为:数据类型>>运算>>语法,语句>>对象>>数组>>函数>>类 什么是数组:数组是一种非常常用的数据结构,用于存储一组有序的值。这些值可以是数字、字符串、对象&#xff…

深入理解 Docker 及常用命令

在云计算与容器化技术飞速发展的今天,Docker 已成为开发者必备的核心技能。本文将从底层原理到实战操作,系统梳理 Docker 的核心知识体系,结合大量实操案例帮助读者快速掌握容器化部署的全流程。 一、Docker 核心概念与底层原理 1.1 容器技…

【卫星通信】卫星与5G深度融合的架构研究——释放非地面网络潜能,构建全球无缝连接【3GPP TR 23.700-19 V0.1.0 (2025-04)】

引言 随着5G网络部署的持续推进,卫星通信在覆盖偏远地区、保障应急通信等场景中的重要性日益凸显。3GPP Technical Report(TR)23.700-19 V0.1.0(2025-04)作为Release 20阶段的最新研究成果,系统性地探讨了…

kicad运行时出错,_Pnext->_Myproxy = nullptr;访问内存出错

花费了比较长的时间,解决了编译过程中遇到的许多问题后,终于把这个开源的工程编译好了,运行post build 脚本将需要的链接文件拷贝好。正当我以为没有任何问题了,双击可执行程序运行。 结果运行起来的时候报错了,提示无…

资深Java工程师的面试题目(一)并发编程

以下是几道针对Java并发编程的面试题,涵盖基础知识、高级概念和实际应用场景,适合资深Java工程师的面试评估: 1. 线程池与任务调度 题目: 描述Java线程池的核心参数(如corePoolSize、maximumPoolSize、keepAliveTime等&#xff…

解决Spark4.0.0依赖问题

Apache Spark 4.0.0 冲突解决指南 1. 问题背景 在尝试运行一个基于 Apache Spark 4.0.0 的 Java 应用程序。根据 Spark 4.0.0 的发布说明,该版本默认支持 Scala 2.13 和 JDK 17。在初始设置和运行过程中,遇到了以下主要问题: 依赖冲突 (PO…

什么是SeaTunnel

SeaTunnel:高性能、分布式数据集成平台 1. 什么是SeaTunnel? SeaTunnel(原名Waterdrop)是一个高性能、分布式、可扩展的数据集成平台,专为大规模数据同步、ETL(Extract, Transform, Load)和实…

Android 使用OkHttp 下载文件失败问题定位和修复

一、背景 使用Okhttp下载文件时,存在失败情况,刚开始以为是网络问题,后面添加相关日志发现,是在网络波动比较大的情况下,被判为timeout超时,结束了下载任务。 二、解决方案 有问题的下载配置写法: 注:这里只是展示配置下载的关键代码 val client OkHttpClient()val request…

【Docker基础】Docker核心概念:命名空间(Namespace)之PID详解

目录 引言 1 基础概念回顾 1.1 命名空间概述 1.2 命名空间的类型 2 PID命名空间详解 2.1 PID命名空间的概念 2.2 PID命名空间的作用 2.3 PID命名空间的工作原理 2.3.1 PID命名空间的创建与销毁 2.3.2 PID命名空间的层次结构 2.3.3 PID命名空间的进程ID映射 3 PID命…