数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。
线性表
线性表是最基本、最简单、也是最常用的一种数据结构。线性表中除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。
顺序存储结构的线性表、链式存储结构的线性表(即链表)、栈、队列、串都属于线性表的范畴。
顺序存储结构的线性表
在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构。
优点:查找快(因为地址连续,所以只要找到一个,其他的很快就找到)
缺点:插入和删除操作需要移动元素,速度慢
链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
优点:插入和删除操作快
缺点:查找慢
栈
先进后出的数据结构,只能在栈顶进行插入和删除。
栈的一个重要的作用就是记忆功能。栈保存了一个函数调用时所需要的维护信息,这常常称之为堆栈帧或者活动记录。堆栈帧一般包含如下几方面的信息:
- 函数的返回地址和参数
- 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
队列
先进先出的数据结构,只能在队列的后端进行插入操作,只能在队列的前端进行删除操作。
字典
我们把字典定义为“键-值对”(Key-Value Pair)的集合。
从字典中查找“键- 值对”的最简单方法就是使用数组存储,然后在查找的时候遍历此数组,当遍历到和被查找的“键 - 值对”的名字相同项的时候,这个“键 - 值对”就被找到了。这种最朴实的方式肯定是不能满足实际要求的,因此人们发明了一种检索效率非常高的组织字典数据的方法 ,即哈希表结构。
哈希表
哈希方法将 “键-值对”的存储位置 和 “键-值对”的键 建立起一种对应的函数关系hash(),同过哈希函数,能够为每一个键找到一个存储位置。即
存储位置=hash(键)
哈希表也被称作散列表。
当查找一个键所对应的值的时候,首先通过哈希函数取得此“键-值对”的存储位置,然后直接在此存储位置查找,如果键相等,则查找成功。
举个例子,有一组键-值对如下:
<5, "Tom">、<8, "Jane">、<12, "Bit">、<17, "Lily">、<20, "sunny">
我们按照如下哈希函数对键进行计算:
hash(x)=x%17+3
得出如下结果:
hash(5)=8、 hash(8)=11、 hash(12)=15、 hash(17)=3、 hash(20)=6
因此,我们把<5, "Tom">、<8, "Jane">、<12, "Bit">、<17, "Lily">、<20, "sunny">分别放在地址为8、11、15、3、6的位置上。当要检索17对应的值的时候,首先计算17的hash值为3,然后到地址为3的存储位置取得17对应的值为Lily,可见检索速度很快
但是有一个问题,不同的键有时候算出来的hash值是同一个,即不同的键-值对放到了同一个存储位置。这个不要紧,检索的时候把对应存储位置的所有键-值对拿出来比较,找到键相等的那个
二叉树
二叉树是每个节点最多有两个子树的有序树(有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树)。
尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。树和二叉树的2个主要差别:
- 树中结点的最大度数没有限制,而二叉树结点的最大度数为2
- 树的结点无左、右之分,而二叉树的结点有左、右之分
完全二叉树:若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层有叶子节点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
满二叉树:除了叶结点外每一个结点都有左右子叶且叶子结点都处在最底层的二叉树
图1 图2 图3
图2是完全二叉树,图3不是完全二叉树
图1是完全二叉树,也是满二叉树
二叉排序树(二叉查找树)
二叉排序树又称二叉查找树。它或者是一棵空树;或者是具有下列性质的二叉树:
- 若左子树不空,则左子树上所有结点的值均小于它的根结点的值
- 若右子树不空,则右子树上所有结点的值均大于它的根结点的值
- 左、右子树也分别为二叉排序树
如下图,就是一个二叉排序树。
二叉排序树查找节点
若根结点的关键字值等于查找的关键字,成功
若大于根结点的关键字值,递归查右子树
若子树为空,查找不成功
二叉排序树插入节点
若当前的二叉查找树为空,则插入的元素为根节点
若插入的元素值小于根节点值,则将元素插入到左子树中;若插入的元素值不小于根节点值,则将元素插入到右子树中
按以上方法递归
注意:新插入的结点总是叶子节点
二叉排序树删除节点(3种情况)
- 要删除的节点是叶子节点。直接删除
- 要删除的节点只有左(右)子树。直接删除并把它的左(右)子树当成它的父节点的左(右)子树
- 要删除的节点的左子树和右子树均不空。可以有两种做法:其一是把要删除节点的左子树的最右下节点代替要删除节点;其二是把要删除节点的直接前驱(或直接后继)代替要删除的节点
二叉平衡树
二叉平衡树是在二叉排序树的基础上得来的。对于一颗二叉排序树,插入、删除、查找所花的时间和树的高度h有关,那么如果能够让树维持矮矮胖胖的身材,那么可以提高效率。所以二叉平衡树就诞生了。
平衡二叉树定义:它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树
B树
B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统