Java数据结构和算法学习笔记

15个常用的数据结构和算法

10个数据结构:数组、链表、栈、队列、跳表、散列表、二叉树、堆、图、Trie树(后三个相对不太重要);
5个算法:递归、排序、二分查找、哈希算法、字符串匹配算法。

时间复杂度

表示执行时间与数据规模之间的关系

时间复杂度量级(由低到高7个):常量阶O(1)、对数阶O(logn)、线性阶O(n)、线性对数阶O(nlogn)、k次方阶O(nk)、指数阶O(2n)、阶乘阶O(n!)。
最好、最坏、平均、均摊时间复杂度
在不同情况下的复杂度分析,可以联想一下从数组中查找某个元素。在能够应用均摊时间复杂度分析的场合,一般均摊时间复杂度就等于最好情况时间复杂度。

空间复杂度

表示存储空间与数据规模之间的关系

空间复杂度量级:常见的空间复杂度就是O(1)、O(n)、O(n2 ),像O(logn)、O(nlogn)这样的对数阶复杂度平时都用不到。

一、数据结构—数组

数组:是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。增删慢,随机访问快。不支持动态扩容。

二、数据结构—链表

链表:是一种线性表数据结构。它用一组非连续的内存空间,来存储一组具有相同类型的数据。增删快,随机访问慢。支持动态扩容。常用单链表,双向链表,循环链表。

单链表:数据+指针,最后一个节点指针指向空地址NULL
循环链表:数据+指针,最后一个节点指针指向头节点地址
双向链表:指针+数据+指针。方便寻找前驱结点和后继节点,以空间换时间的设计思想,效率更高了。

三、数据结构—栈

栈:线性结构,先进后出 U。

四、数据结构—队列

队列:线性结构,先进先出 ||。

五、数据结构—跳表

跳表(增删查都很快):二分查找是基于数组的有序数据集,而跳表是基于链表的一种数据结构,从有序的数据中向上抽取数据做索引,层级越多查找的效率也越高,同时占用的空间也大,是典型的空间换时间的思想。查找,删除,增加数据时间复杂度都是O(logn)。

六、数据结构—散列表(哈希表)

散列表:本质是数组,通过哈希函数取出对应下标里的数据。插入、删除、查找操作的时间复杂度都是O(1)。
散列冲突:数组是有限的,当数据量很大时,通过hash(key)散列函数计算出来的hash值可能是一样的,那么就不能通过键名取得对应的键值,再好的散列函数也无法避免散列冲突。那究竟该如何解决散列冲突问题呢?我们常用的散列冲突解决方法有两类,开放寻址法和链表法。
  • 开放寻址法:如果通过哈希函数计算出来的哈希值是重复的,说明存储位置已经被占用了,我们就从当前位置开始,依次往后查找,看是否有空闲位置,直到找到空闲位置将数据存入。
  • 链表法:将数据存到链表里。
    在这里插入图片描述

七、数据结构—树

首先要了解下几个概念,高度(Height)、深度(Depth)、层(Level)。它们的定义是这样的:
在这里插入图片描述
二叉树:每个节点最后有两个叉。想要存储一棵二叉树,我们有两种方法,一种是基于指针或者引用的二叉链式存储法,一种是基于数组的顺序存储法。我们先来看比较简单、直观的链式存储法。这种存储方式我们比较常用。大部分二叉树代码都是通过这种结构来实现的。
在这里插入图片描述
用数组存储二叉树数据容易浪费空间,一般完全二叉树用数组存放数据是比较合适的。
在这里插入图片描述
在这里插入图片描述
二叉树的遍历:时间复杂度是O(n)

  • 前序遍历:根左右
  • 中序遍历:左根右
  • 后序遍历:左右根

二叉树的分类:

  • 完全二叉树:高度是1和2的节点可以只有左子树,其余节点都是两个叉。
  • 二叉查找树:中序遍历后的树是一个从小到大的数据集。
  • 平衡二叉查找树:满足二叉查找树的同时任何节点的左右子树高度相差不超过1。平衡二叉查找树是为了避免在特殊情况下二叉查找树退化成链表导致性能变差的问题。红黑树是一种特殊的平衡二叉查找树,插入、删除、查找操作的时间复杂度都是O(logn)。

红黑树与跳表的对比:
二者时间复杂度都是log(n),因为红黑树是一种性能非常稳定的平衡二叉查找树,所以,在工程中,但凡是用到动态插入、删除、查找数据的场景,都可以用到它。不过,它实现起来比较复杂,如果自己写代码实现,难度会有些高,这个时候,我们其实更倾向用跳表来替代它。

八、数据结构—堆

堆:一种特殊的树。只要满足这两点,它就是一个堆。堆是一个完全二叉树;堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值。

九、数据结构—图

图的概念比较多,但是很简单,一般存储图有两种方式:邻接矩阵存储(底层是二维数组),此方式存储比较浪费空间;邻接表存储(底层是链表)。

图的“搜索算法”:广度优先遍历搜索和深度优先遍历搜索。
深度优先搜索:它其实就是一种“地毯式”层层推进的搜索策略,即先查找离起始顶点最近的,然后
是次近的,依次往外搜索。理解起来并不难,所以我画了一张示意图。
在这里插入图片描述
深度优先遍历:假设你站在迷宫的某个岔路口,然后想找到出口。你随意选择一个岔路口来走,走着走着发现走不通的时候,你就回退到上一个岔路口,重新选择一条路继续走,直到最终找到出口。这种走法就是一种深度优先搜索策略。深度优先搜索找出来的路径,并不是顶点s到顶点t的最短路径。见下图:
在这里插入图片描述

十、数据结构—Trie树

Trie树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符串匹配的数据结构,用来解决在一组字符串集合中快速查找某个字符串的问题。举个简单的例子来说明一下。有6个字符串,它们分别是:how,hi,her,hello,so,see。我们希望在里面多次查找某个字符串是否存在。下图是用Trie的快速解决办法:

在这里插入图片描述
Trie树一般用来做搜索关键词提示,如下图:
在这里插入图片描述

一、算法—递归

满足一下三个条件即可用递归:

  1. 一个问题的解可以分解为几个子问题的解
  2. 这个问题与分解之后的子问题,除了数据规模不同,求解思路完全一样
  3. 存在递归终止条件

二、算法—排序

排序算法有很多,主要了解下面8个就够了。比较算法可以从执行效率(时间复杂度)、内存消耗(空间复杂度)和稳定性这三方面衡量。(假设是从小到大排)	
  1. 冒泡排序:两两比较。
  2. 插入排序:两区间,即已排序区间和未排序区间。
  3. 选择排序:两区间,即已排序区间和未排序区间。从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
  4. 归并排序: 分成一半,排完再合并。
  5. 快速排序:选一基点,小的数据放基点左边,大的数据放基点右边。
  6. 基于快排的桶排序:其实就是将数据分类放到不同的桶里,每个桶里的数据再用快排进行排序。
  7. 计数排序:特殊的桶排序。思考50万考生,满分制是900分,利用桶排序查名词。
  8. 基数排序:高低位进行比较。思考10万个手机号码从小到大排序问题。
    在这里插入图片描述

三、算法—二分查找

在一个有序的数据集合里(底层依赖数组)查找某元素。时间复杂度O(logn)。

四、算法—哈希算法

见数据结构—散列表(哈希表)那一节。

五、算法—字符串匹配

主要介绍四种字符串匹配算法
1、BF算法(暴力匹配算法、朴素匹配算法),见下图。
2、RK算法:对主串求哈希值,然后和子串的哈希值对比,因为哈希值是一个数字,数字之间比较是否相等是非常快速的,所以模式串和子串比较的效率就提高了。
3、BM算法:是在BF的基础上增加了自己的计算,一次向后滑动n个字符。
4、KMP算法:跟BM算法非常相近。我们假设主串是a,模式串是b。在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,我们希望找到一些规律,可以将模式串往后多滑动几位,跳过那些肯定不会匹配的情况。

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值