常用数据结构及其应用场景

 常用数据结构及其应用场景

 

目录

1,数组

2,链表

3,树

3.1 二叉搜索树

3.2 AVL树

3.3红黑树

补充:关于AVL树和红黑树的左旋与右旋

右旋

左旋


思维导图

 

常用数据结构及其应用场景_第1张图片

1,数组

这是大家最熟悉的数据结构了;

数组的优势:

  1. 随机访问(按下标访问):时间复杂度O(1)
  2. 正常查找一个元素,时间复杂度O(n)
  3. 如果数组是有序的,升序或者降序,使用二分查找,时间复杂度O(logN),N为数组长度

劣势:

  1. 除去首部和尾部,在中间插入或者删除元素,都要导致大量数据的移动

使用场景:

常查询,少插入或者删除的情况

2,链表

链表的优势:

  1. 查询时间复杂度:时间复杂度O(N),N为链表长度
  2. 插入或者删除不需要移动大量的元素,因为链表本身就是非连续的存储

劣势:

  1. 查询,删除,在给定位置插入元素的时间复杂度都是O(N)这点一直被人诟病
  2. 后续提出的双向链表,只是提高的删除结点的时间复杂度,其余都一样,直到跳表的出现,降低了链表查询的时间复杂度

使用场景:

多插入或者删除,少查询的情况

 

对CPU来说,数据更友好一些,因为CPU从内存中读取内容,假设数组是int类型,并不是每次都读取一个数字,4KB,而是读取一个数据块,放入到CPU缓存(cache)中,下次想从CPU的缓存中找,CPU缓存比内存的读写要快,所以对于连续存储的数据来说,连续访问或者遍历时,对CPU是较为友好的。

3,树

从计算机行业的发展可以看出,基本是朝着更快更高并发更便宜的方向狂奔不止的,并发数量要求高,响应速度要求也高,数据量极大,那么像数组,链表这种数据结构,在大数据量面前,基本丧失了所有该有的优势功能。

3.1 二叉搜索树

树很好的解决了这些问题,尤其是 二叉查找/搜索(sort)树

二叉查找树有如下的性质:

  1. 左子树不为空,则左子树上所有结点的值均小于它的根结点的值
  2. 右子树不为空,所有右子树上所有结点的值均大于根结点的值
  3. 根结点的左右子树也是一颗二叉排序树。

看上去就完美的设定,查找时间复杂度O(logN)(log以2为底N的对数,其中N是树的深度)

但是当我们输入一串有顺序的数组后,二叉查找树就会完全退化为一个链表,查找时间复杂度O(N)

3.2 AVL树

为了解决这个问题,现在规定每个结点的左孩子结点都小于该结点,右孩子结点都大于根结点,且左右子树的高度差不大于1

但是平衡二叉树有个致命的问题:

那么为了解决这个问题,提出了AVL数,即完全平衡二叉树,每次插入一个结点,都需要使用左旋、右旋、左旋与右旋的组合来维持平衡,即每个结点的左孩子结点小于根结点,根结点小于右孩子结点,且左右子树的高度差不大于1,为了达到完全平衡,AVL树付出了太多的代价。效率不高。

为了解决这个效率问题和二叉查找树退化链表的问题,提出了红黑树

3.3红黑树

红黑树有以下特点:

  1. 每个结点不是红色就是黑色
  2. 红色结点不可能有连在一起的
  3. 结点都是黑色:入度为0
  4. 每个红色结点的连接子结点都是黑色
  5. 叶子结点都是黑色(NULL):出度为0
  6. 每个结点,从该结点到达其可达叶子结点的所有路径,都包含相同数目的黑色结点

 

如果说完全平衡二叉树是通过左旋,右旋,左旋和右旋的组合,保证每个结点的左孩子都小于根结点,右孩子都大于根结点,且左右子树的高度差不大于1

那么红黑树就是通过变色,左旋,右旋,左旋和右旋的组合,保证结点之间红黑间隔,每个结点到叶子结点经过的黑色结点个数都是一样的,以此来保持平衡

红黑树处理插入结点的规则:

常用数据结构及其应用场景_第2张图片

插入的点默认是红色

变颜色情况:

当前结点的父亲结点是红色,且叔叔结点也是红色,红色结点不能相连,那么使用变色进行处理:

  1. 把父亲结点变为黑色
  2. 把叔叔结点变为黑色
  3. 把祖父变成红色

把指针定义到祖父结点,查看是否符合红黑树的定义,不符合则进行变色或者左旋或右旋

 

补充:关于AVL树和红黑树的左旋与右旋

(来自大话数据结构)

右旋

常用数据结构及其应用场景_第3张图片

常用数据结构及其应用场景_第4张图片

左旋

常用数据结构及其应用场景_第5张图片

你可能感兴趣的:(数据结构部分,数据结构,链表,二叉树)