数据结构

什么是数据结构

数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。

数据结构与算法密切相关,这里只介绍数据结构。

定义
数据结构(data structure)是带有结构特性的数据元素的集合,它研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法,并确保经过这些运算以后所得到的新结构仍保持原来的结构类型。简而言之,数据结构是相互之间存在一种或多种特定关系的数据元素的集合,即带“结构”的数据元素的集合。“结构”就是指数据元素之间存在的关系,分为逻辑结构和存储结构。

数据的逻辑结构和物理结构是数据结构的两个密切相关的方面,同一逻辑结构可以对应不同的存储结构。算法的设计取决于数据的逻辑结构,而算法的实现依赖于指定的存储结构。

数组(Array)

数组是用于储存多个相同类型数据的集合。它占据一块连续的内存,而且是顺序存储结构。在创建数组时必须要指定数组的容量大小,在根据数组容量来分配内存。数组可以说是线性表的顺序存储结构。

优点

  • 因为数组的内存是连续的,它的存取时间性能为O(1),因此它的时间效率是很高的。

缺点

  • 需要预先知道数据规模,申请内存大小
  • 插入、删除效率低

应用场景

  • 数据量小
  • 数据大小已知
  • 对数据存取和修改操作较多,而插入和删除数据较少的情况
链表(Linked List)

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

优点

  • 使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理
  • 插入、删除时间复杂度为O(1)

缺点

  • 没有数组随机读取的优点,读取的复杂度O(n)
  • 链表由于增加了结点的指针域,空间开销比较大

应用场景

  • 不需要预先知道数据大小
  • 适用于插入删除操作较多,而存取操作较少的情况
栈和队列(Stack、Queue)

栈和队列是特殊的线性表结构,都是运算受限的线性表。

栈(Stack): 栈是一种只能从表的一端存取数据且遵循 “先进后出” 原则的线性存储结构。
栈的链式存储结构称为链栈,是运算受限的单链表。其插入和删除操作只能在表头位置进行。因此,链栈没有必要像单链表那样附加头结点,栈顶指针top就是链表的头指针。

应用

  • 实现递归
  • 四则运算表达式求值

队列(Queue): 对列是运算受限的线性表只允许在一端插入而在另一端删除。是一种先进先出(First In First Out ,简称FIFO)的线性表。
队列的链式存储结构简称为链队列,它是限制仅在表头进行删除操作和表尾进行插 入操作的单链表。需要两类不同的结点:数据元素结点,队列的队首指针和队尾指针的结点。

应用

  • 各种MQ的实现思路
  • 有先后操作的业务都可以用
树(Tree)

树是典型的非线性结构,它是包括,2个结点的有穷集合K。在树结构中,有且仅有一个根结点,该结点没有前驱结点。在树结构中的其他结点都有且仅有一个前驱结点,而且可以有两个后继结点,m≥0。

二叉树
二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

二叉排序树就既有链表的好处,也有数组的好处。

优点

  • 查找效率较高,时间复杂度为O(log n)

缺点

  • 可能变成斜的二叉树,相当于线性表。所以有平衡二叉树的改进。
  • 数据量大的时候树的的深度太高

平衡二叉树(AVL)
平衡二叉树——平衡二叉树又被称为AVL树(区别于AVL算法),它是一棵二叉排序树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。

优点

  • 二叉树的优点都具备,且左右子树的高度不会出现大的偏差,不超过1

缺点

  • 添加、删除元素都需要通过旋转来达到树的再次平衡。二叉平衡树的严格平衡策略以牺牲建立查找结构(插入,删除操作)的代价,换来了稳定的O(logN) 的查找时间复杂度。为此改进了红黑树。

红黑树(Red-Black Tree)
R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种平衡二叉树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。

由于红黑树的性质(最长路径长度不超过最短路径长度的2倍),可以说明红黑树虽然不像AVL一样是严格平衡的,但平衡性能还是要比BST要好。其查找代价基本维持在O(logN)左右,但在最差情况下(最长路径是最短路径的2倍少1),比AVL要略逊色一点。

RBT插入结点时,需要旋转操作和变色操作。但由于只需要保证RBT基本平衡就可以了。因此插入结点最多只需要2次旋转,这一点和AVL的插入操作一样。虽然变色操作需要O(logN),但是变色操作十分简单,代价很小。

优点

  • RBT的删除操作代价要比AVL要好的多,删除一个结点最多只需要3次旋转操作
  • 查找 效率最好情况下时间复杂度为O(logN),但在最坏情况下比AVL要差一些,但也远远好于BST
  • 插入和删除操作改变树的平衡性的概率要远远小于AVL(RBT不是高度平衡的)。因此需要的旋转操作的可能性要小,而且一旦需要旋转,插入一个结点最多只需要旋转2次,删除最多只需要旋转3次(小于AVL的删除操作所需要的旋转次数)。虽然变色操作的时间复杂度在O(logN),但是实际上,这种操作由于简单所需要的代价很小。

B-树(B-Tree)
B-Tree作为一个平衡多路查找树(m-叉)。B树的查找分成两种:一种是从一个结点查找另一结点的地址的时候,需要定位磁盘地址(查找地址),查找代价极高。另一种是将结点中的有序关键字序列放入内存,进行优化查找(可以用折半),相比查找代价极低。而B树的高度很小,因此在这一背景下,B树比任何二叉结构查找树的效率都要高很多。而且B+树作为B树的变种,其查找效率更高。

B+树(B+Tree)
B+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+树包含根节点、内部节点和叶子节点。根节点可能是一个叶子节点,也可能是一个包含两个或两个以上孩子节点的节点。

应用

  • 数据库索引、操作系统的文件系统
堆(Heap)

堆是一种特殊的树形数据结构,一般讨论的堆都是二叉堆。堆的特点是根结点的值是所有结点中最小的或者最大的,并且根结点的两个子树也是一个堆结构。

堆总是满足下列性质:

  • 堆中某个节点的值总是不大于或不小于其父节点的值;
  • 堆总是一棵完全二叉树。

应用

  • 堆排序
  • 优先级队列
  • 海量数据topk问题
  • 求动态集合中位数
图(Graph)

图是另一种非线性数据结构。在图结构中,数据结点一般称为顶点,而边是顶点的有序偶对。如果两个顶点之间存在一条边,那么就表示这两个顶点具有相邻关系。

应用

  • 深度优先搜索(DFS)
  • 广度优先搜索(BFS)
  • 计算最短路径算法
  • 关键路径算法
  • 拓扑排序算法
散列表(Hash)

散列表源自于散列函数(Hash function),其思想是如果在结构中存在关键字和T相等的记录,那么必定在F(T)的存储位置可以找到该记录,这样就可以不用进行比较操作而直接取得所查记录。

优点

  • 查找速度快,不考虑冲突,时间复杂度O(1)。即使冲突也很快。

缺点

  • 哈希冲突,解决方法有再散列法、链表法(拉链法)、建立一个公共溢出区
  • 关键字分布无规律,无法排序,无法按范围查询
  • 删除慢,如果不知道关键则存取很慢,对存储空间使用不充分

应用

  • 数据库索引
  • 适用等值查找的情况,如爬虫url去重,垃圾邮件,判断集合是否存在某数据等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值