数据结构

数组:采用一段连续的存储单元存储数据。对于指定下标的查找,其时间复杂度为O(1)。对于数组的插入、删除等元素移动操作则时间复杂度为O(n)。

链表:对于链表的新增、删除等操作,其时间复杂度为O(1)。对于链表的查找,时间复杂度为O(n)。

ArrayList线性表:底层是一个数组与代表数组元素个数的size。当进行增加操作时,在数组后添加该元素,并size = size + 1 

LinkedList链表:底层是一个Node类,当加入一个新元素时,会指定该node上一个node元素与下一个node元素,因此插入删除很方便。

 

栈:后进先出     队列:先进先出

 

二叉树:每个节点的孩子树只能是0、1和2个,并且有左右之分。java构件二叉树时会指定该节点值,左子树节点与右子树节点。

节点的度:一个节点拥有的子树数目。

叶子节点:度为0的节点。

 

先序遍历DLR: 根 左子树 右子数                                                                                                       

中序遍历LDR:左子树 根 右子树                                                                                                         

后序遍历LRD:左子树 右子树 根

 

满二叉树:每层节点都达到最大数。若在满二叉树中,在最下层从最右侧开始去掉相邻的若干接点,则成为完全二叉树。

二叉查找树:左子树节点均小于该根节点,右子树节点均大于该根节点。

平衡二叉树:又被称为AVL数。在二叉查找树的基础上左右子树高度差不超过1。并且左右子树都是平衡树。

 

平衡二叉树很好的解决了二叉查找树退化成链表的问题,保证了插入、删除、查找的时间复杂度都稳定在O(logn)。

平衡二叉树的查找速度很快,但维护一颗平衡二叉树的代价很大。当插入一个新值后,需要一次或多次左旋或右旋来来保持树的平衡性。

 

 

红黑树

也是一种二叉查找树,但在每个节点增加一个存储位表示节点的颜色,可以是红或黑(非红即黑)。通过对任何一条从根到叶子的路径上各个节点着色的方式的限制,红黑树确保没有一条路径会比其它路径长出两倍,因此,红黑树是一种弱平衡二叉树(由于是弱平衡,可以看到,在相同的节点情况下,AVL树的高度低于红黑树),相对于要求严格的AVL树来说,它的旋转次数少,所以对于搜索,插入,删除操作较多的情况下,我们就用红黑树。

 

 

  • 每个节点非红即黑
  • 根节点为黑色
  • 所有叶子节点都是黑色
  • 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)
  • 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点(简称黑高)。

 

B树与B+树

 B树是一种平衡的多路查找树。一颗m阶B数或为空树,或为满足如下特性的m叉树。 m阶是指每个节点最多拥有m个子节点。

  • 树中每个节点最多有m棵子树。(即最多有m-1个关键字)
  • 若根节点不是终端节点,则至少有2棵子树。(至少1个关键字)
  • 除根节点外的所有非叶结点至少有[m/2]棵子树。(至少有[m/2]-1个关键字) 向上取整
  • 关键字按从左至右递增次序排列
  • 所有叶子节点位于同一层层次。

 

(25,50,60,75...)为关键字,下面引出来的即为子树。5棵子树,4个关键字。

 B数是多路查找,二叉树是二路查找。

 

B+数

用于数据库和操作系统的文件系统中的一种用于查找的数据结构。

m阶B+数与m阶B数的主要区别

  • 在B+树中,具有n个关键字的节点只含有n棵子树,即一个关键字对应一个子树;而在B树中,具有n个关键字的节点含有n+1棵子树。
  • 在B+树中,每个节点(非根内部节点)关键字个数的范围是m/2至m。在B树中,每个节点(非根内部节点)关键字个数范围是m/2-1至m-1。
  • 在B+树中,叶节点包含信息,所有非叶节点仅起到索引作用。非叶节点中的每个索引项只含有对应子树的最大关键字和指向该子树的指针,不含有该关键字对应记录的存储地址。
  • 在B+树中,叶节点包含了全部关键字关键字自小到大顺序连接,即在非叶节点中出现的关键字也会出现在叶节点中;而在B树中,叶节点包含的关键字和其他节点包含的关键字是不重复的。

 

 为什么B+树比B树更加适合索引?

  • 磁盘读写代价更低。B+树内部结构没有指向关键字具体信息的指针,这样内部结点相对B树更小
  • B+树查询更加稳定。因为非终端结点并不是最终指向文件内容的结点,仅仅是作为叶子结点中关键字的索引。这样所有的关键字的查找都会走一条从根到叶子结点的路径。所有的关键字查询长度是相同的,查询效率高

 

设计索引的最终目的:减少磁盘I/O次数

局部性原理与磁盘预读:
由于存储介质的特性,磁盘本身存取就比主存慢很多,再加上机械运动耗费,磁盘的存取速度往往是主存的几百分分之一,因此为了提高效率,要尽量减少磁盘I/O。为了达到这个目的,磁盘往往不是严格按需读取,而是每次都会预读,即使只需要一个字节,磁盘也会从这个位置开始,顺序向后读取一定长度的数据放入内存。这样做的理论依据是计算机科学中著名的局部性原理:
当一个数据被用到时,其附近的数据也通常会马上被使用。
程序运行期间所需要的数据通常比较集中。
由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,预读可以提高I/O效率。

使用红黑树(平衡二叉树)结构的话,每次磁盘预读中的很多数据是用不上的数据。因此,它没能利用好磁盘预读的提供的数据。然后又由于深度大(较B树而言),所以进行的磁盘IO操作更多。

B树的每个节点可以存储多个关键字,它将节点大小设置为磁盘页的大小,充分利用了磁盘预读的功能。每次读取磁盘页时就会读取一整个节点。也正因每个节点存储着非常多个关键字,树的深度就会非常的小。进而要执行的磁盘读取操作次数就会非常少,更多的是在内存中对读取进来的数据进行查找。

B树的查询,主要发生在内存中,而平衡二叉树的查询,则是发生在磁盘读取中。因此,虽然B树查询查询的次数不比平衡二叉树的次数少,但是相比起磁盘IO速度,内存中比较的耗时就可以忽略不计了。因此,B树更适合作为索引。

比B树更适合作为索引的结构是B+树。MySQL中也是使用B+树作为索引。它是B树的变种,因此是基于B树来改进的。为什么B+树会比B树更加优秀呢?
B树:有序数组+平衡多叉树;
B+树:有序数组链表+平衡多叉树;

B+树的关键字全部存放在叶子节点中,非叶子节点用来做索引,而叶子节点中有一个指针指向一下个叶子节点。做这个优化的目的是为了提高区间访问的性能。而正是这个特性决定了B+树更适合用来存储外部数据。

 
 

posted @ 2020-03-11 00:34  xxcnotes  阅读(147)  评论(0)    收藏  举报