数据结构与算法

215 阅读6分钟

算法时间复杂度表示方式

  • 常数: O(1)
  • 线性: O(N)
    • 单循环
  • 对数: O(N log N)
    • 递归、分治策略(时间减少1/2的算法就可以用O(N log N))、二分法
  • 指数: N^2
    • 嵌套循环

####数据结构

  • 数组:固定容量容器
  • 列表:自定义封装容易,实现动态自动调整容量,需要了解扩容机制
  • 链表:链表和列表相比,添加和删除较快,查需需要从头开始扫描,不支持随机读取。可用链表实现队列和栈功能
  • 队列:先进先出功能,数据接口内部包含下一个节点。
  • 栈:后进先出。

  • 树的基本概要
    • 根节点
    • 节点
    • 路径
    • 叶子
    • 深度
    • 树节点关系数据结构
	public class TreeNode<T>{
	/**
	 * 节点信息
	 */
	T t;
	
	/**
	 * 第一个孩子节点
	 */
	TreeNode firstChild;
	
	/**
	 * 下一个兄弟节点
	 */
	TreeNode nextSibling;
	} 
  • 二叉树:每个节点最多只有2个子节点,缺点:树的深度容易太深
	public class TreeNode<T>{
	/**
	 * 节点信息
	 */
	T t;
	
	/**
	 * 左节点
	 */
	TreeNode left;
	
	/**
	 * 右节点
	 */
	TreeNode right;
	} 
  • 二叉查找树(Binary Sort Tree):左边的节点值总是小于父节点,右边的节点值总是大于节点值,遍历都是根据根节点的顺序命名,遍历时从根节点出发
  1. 前序遍历:先根节点-->左子树-->右子树,可以用来实现目录结构的显示。
  2. 中序遍历:左子树-->根节点-->右子树,可以用来做表达式树,在编译器底层实现的时候用户可以实现基本的加减乘除,比如 a*b+c。
  3. 后续遍历:左子树-->右子树-->先根节点,后序遍历可以用来实现计算目录内的文件占用的数据大小~非常有用。
  • 平衡二叉查找树(Balance Binary Sort Tree)也叫AVL:任意的左右子树高度差的绝对值不超过1

    • 插入节点在外边
      • 左左:右单旋转
      • 右右:左单旋转
      • 左右:先向左旋转,然后再向右旋转
      • 右左:先向右旋转,然后向左旋转
  • 红黑树定义条件

  1. 每个结点都是红色或黑色的
  2. 根结点是黑色的(是红色最终也会转黑色)
  3. 所有叶子结点都是黑色的,这里的叶子结点指的是空结点,常用NIL表示,java中用null表示
  4. 如果结点为红色,则其子结点均为黑色(红色表示可与父结点合并,子结点凑什么热闹)
  5. 从给定结点到其任何后代NIL结点的每条路径都包含相同数量的黑色节点(转成 2-4 树,所有叶子节点均在最底层)
  • AVL树和红黑树区别
  1. 红黑树和AVL树都是最常用的平衡二叉搜索树,它们的查找、删除、修改的时间复杂度都是O(logn)
  2. 红黑树并非严格意义上的平衡二叉搜索树,树高可能是AVL树的两倍,所以在查找方面AVL树的效率会更高一些。
  3. 插入和删除方面,AVL树速度较慢:需要更高的旋转次数才能在修改时正确地重新平衡数据结构,而红黑树将需要最多两次旋转使其达到平衡
算法名称 查找 修改 删除
AVL O(logN) NO(logN) NO(logN)
红黑树 2O(logN) 2 2
  • 平衡多叉查找树
  1. B-树:平衡多叉查找树,节点会存放原始数据。
  2. B+树:平衡多叉查找树,有的原始数据都存放在子节点上,子节点前后相链接。
  • 终结:
  1. 能用平衡树的地方,就可以用红黑树。用红黑树之后,读取略逊于AVL,维护强于AVL。

  2. 红黑树和B+树的用途有什么区别?

    • 红黑树多用在内部排序,即全放在内存中的,Java集合框架HashMap和HashSet等内部实现就是红黑树。
    • B+树多用于外存上时,B+也被成为一个磁盘友好的数据结构。
  3. 为什么B+树磁盘友好?

  • 磁盘读写代价更低,树的非叶子结点里面没有数据,这样索引比较小,可以放在一个blcok(或者尽可能少的blcok)里面。避免了树形结构不断的向下查找,然后磁盘不停的寻道,读数据。这样的设计,可以降低io的次数。
  • 查询效率更加稳定,非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
  • 遍历所有的数据更方便,B+树只要遍历叶子节点就可以实现整棵树的遍历,而其他的树形结构要中序遍历才可以访问所有的数据

4.为什么mysql索引使用b+树而不使用红黑树?

  • B+树就是为文件存储而生的。如果数据库文件存储在主存中我认为两种结构的查询速度差距不是很大,因为主存的查找速度非常快。而数据库文件实际存储在磁盘中,定位一行信息需要查找该行文件所在柱面号,磁盘号,扇区号,页号这个阶段是很耗费时间的。每一次的定位请求意味着要做一次IO操作,也意味着成倍的时间消耗。因此减少IO查询的次数是提高查询性能的关键。而IO的查询次数就是索引树的高度,高度越低查询的次数越少。同样的结点次数红黑树的高度最多为2log(n+1),而B+树的高度最多为(logt (n+1)/2)+1,随着t增大高度会更小,IO次数也会减少。

  1. 图定义:有向图、无向图、带权值的网图、稀疏图

  2. 图存储结构

  • 邻接矩阵:数组[存储节点数]+节点关系二维数组[横向节点][纵向节点]

    邻接矩阵结构图

  • 邻接表法: 数组[存储节点数]-->节点关系1-->节点关系2--> ...

    邻接矩阵结构图

  • 十字链表法: 数组[存储节点数]-->节点关系1-->节点关系2--> ... -->反向节点关系1-->反向节点关系2--> ...

    十字链表法

  1. 图遍历
  • 深度优先:确定一个方向一直搜索直到无路可走,才返回走另外一个方向。
    • 优点
    1. 能找出所有解决方案
    2. 优先搜索一棵子树,然后是另一棵,所以和广搜对比,有着内存需要相对较少的优点
    • 缺点
    1. 要多次遍历,搜索所有可能路径,标识做了之后还要取消。
    2. 在深度很大的情况下效率不高
  • 广度优先:先查询所有的一度关系节点,然后保存下来遍历二度关系节点,直到所有的节点遍历完毕。
    • 优点
    1. 对于解决最短或最少问题特别有效,而且寻找深度小
    2. 每个结点只访问一遍,结点总是以最短路径被访问,所以第二次路径确定不会比第一次短
    • 缺点
    1. 内存耗费量大(需要开大量的数组单元用来存储状态)

来源