Skip to content

Commit 5c79aca

Browse files
Update 数据结构与算法.md
1 parent 463722a commit 5c79aca

File tree

1 file changed

+53
-34
lines changed

1 file changed

+53
-34
lines changed

数据结构与算法.md

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,85 @@
11
## 数据结构与算法
22

3+
4+
* [1.什么是算法?](#1什么是算法)
5+
* [2.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?](#2treemap和treeset在排序时如何比较元素collections工具类中的sort方法如何比较元素)
6+
* [3.如何知道二叉树的深度?](#3如何知道二叉树的深度)
7+
* [4.介绍一下,堆排序的原理是什么?](#4介绍一下堆排序的原理是什么)
8+
* [5.数组和链表的区别](#5数组和链表的区别)
9+
* [6.二分查找了解过吗?](#6二分查找了解过吗)
10+
* [7.说下你熟悉的排序算法](#7说下你熟悉的排序算法)
11+
* [8.布隆过滤器了解过吗?](#8布隆过滤器了解过吗)
12+
* [9.一致性hash算法了解过吗?](#9一致性hash算法了解过吗)
13+
* [10.如何在一个1到100的整数数组中找到丢失的数字?](#10如何在一个1到100的整数数组中找到丢失的数字)
14+
* [11.请你讲讲LRU算法的实现原理?](#11请你讲讲lru算法的实现原理)
15+
* [12.为什么要设计后缀表达式,有什么好处?](#12为什么要设计后缀表达式有什么好处)
16+
* [13. 什么是B树?](#13-什么是b树)
17+
* [14.什么是B+树?](#14什么是b树)
18+
* [15.谈一谈,id全局唯一且自增,如何实现?](#15谈一谈id全局唯一且自增如何实现)
19+
* [参考链接](#参考链接)
20+
21+
322
#### 1.什么是算法?
423

5-
 **算法简单来说就是解决问题的步骤。**
24+
算法简单来说就是解决问题的步骤。
625

7-
  在Java中,算法通常都是由类的方法来实现的。前面的数据结构,比如链表为啥插入、删除快,而查找慢,平衡的二叉树插入、删除、查找都快,这都是实现这些数据结构的算法所造成的。后面我们讲的各种排序实现也是算法范畴的重要领域。
26+
在Java中,算法通常都是由类的方法来实现的。前面的数据结构,比如链表为啥插入、删除快,而查找慢,平衡的二叉树插入、删除、查找都快,这都是实现这些数据结构的算法所造成的。后面我们讲的各种排序实现也是算法范畴的重要领域。
827

9-
  一**、算法的五个特征**
28+
、算法的五个特征
1029

11-
  **①、**`有穷性:对于任意一组合法输入值,在执行又穷步骤之后一定能结束,即:算法中的每个步骤都能在有限时间内完成。`
30+
①、`有穷性:对于任意一组合法输入值,在执行又穷步骤之后一定能结束,即:算法中的每个步骤都能在有限时间内完成。`
1231

13-
  **②、**确定性:在每种情况下所应执行的操作,在算法中都有确切的规定,使算法的执行者或阅读者都能明确其含义及如何执行。并且在任何条件下,算法都只有一条执行路径。
32+
②、确定性:在每种情况下所应执行的操作,在算法中都有确切的规定,使算法的执行者或阅读者都能明确其含义及如何执行。并且在任何条件下,算法都只有一条执行路径。
1433

15-
  **③、**`可行性:算法中的所有操作都必须足够基本,都可以通过已经实现的基本操作运算有限次实现之。`
34+
③、`可行性:算法中的所有操作都必须足够基本,都可以通过已经实现的基本操作运算有限次实现之。`
1635

17-
  **④、**有输入:作为算法加工对象的量值,通常体现在算法当中的一组变量。有些输入量需要在算法执行的过程中输入,而有的算法表面上可以没有输入,实际上已被嵌入算法之中。
36+
④、有输入:作为算法加工对象的量值,通常体现在算法当中的一组变量。有些输入量需要在算法执行的过程中输入,而有的算法表面上可以没有输入,实际上已被嵌入算法之中。
1837

19-
  **⑤、**`有输出:它是一组与“输入”有确定关系的量值,是算法进行信息加工后得到的结果,这种确定关系即为算法功能。`
38+
⑤、`有输出:它是一组与“输入”有确定关系的量值,是算法进行信息加工后得到的结果,这种确定关系即为算法功能。`
2039

2140
二、算法的设计原则
2241

23-
  **①、正确性**:首先,算法应当满足以特定的“规则说明”方式给出的需求。其次,对算法是否“正确”的理解可以有以下四个层次:
42+
①、正确性:首先,算法应当满足以特定的“规则说明”方式给出的需求。其次,对算法是否“正确”的理解可以有以下四个层次:
2443

25-
        一、程序语法错误。
44+
一、程序语法错误。
2645

27-
        二、程序对于几组输入数据能够得出满足需要的结果。
46+
二、程序对于几组输入数据能够得出满足需要的结果。
2847

29-
        三、程序对于精心选择的、典型、苛刻切带有刁难性的几组输入数据能够得出满足要求的结果。
48+
三、程序对于精心选择的、典型、苛刻切带有刁难性的几组输入数据能够得出满足要求的结果。
3049

31-
        四、程序对于一切合法的输入数据都能得到满足要求的结果。
50+
四、程序对于一切合法的输入数据都能得到满足要求的结果。
3251

33-
        PS:通常以第 三 层意义的正确性作为衡量一个算法是否合格的标准。
52+
PS:通常以第 三 层意义的正确性作为衡量一个算法是否合格的标准。
3453

35-
  **②、可读性**:算法为了人的阅读与交流,其次才是计算机执行。因此算法应该易于人的理解;另一方面,晦涩难懂的程序易于隐藏较多的错误而难以调试。
54+
②、可读性:算法为了人的阅读与交流,其次才是计算机执行。因此算法应该易于人的理解;另一方面,晦涩难懂的程序易于隐藏较多的错误而难以调试。
3655

37-
  **③、健壮性**:当输入的数据非法时,算法应当恰当的做出反应或进行相应处理,而不是产生莫名其妙的输出结果。并且,处理出错的方法不应是中断程序执行,而是应当返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。
56+
③、健壮性:当输入的数据非法时,算法应当恰当的做出反应或进行相应处理,而不是产生莫名其妙的输出结果。并且,处理出错的方法不应是中断程序执行,而是应当返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。
3857

39-
  **④、高效率与低存储量需求**:通常算法效率值得是算法执行时间;存储量是指算法执行过程中所需要的最大存储空间,两者都与问题的规模有关。
58+
④、高效率与低存储量需求:通常算法效率值得是算法执行时间;存储量是指算法执行过程中所需要的最大存储空间,两者都与问题的规模有关。
4059

41-
  前面三点 正确性,可读性和健壮性相信都好理解。对于第四点算法的执行效率和存储量,我们知道比较算法的时候,可能会说“A算法比B算法快两倍”之类的话,但实际上这种说法没有任何意义。因为当数据项个数发生变化时,A算法和B算法的效率比例也会发生变化,比如数据项增加了50%,可能A算法比B算法快三倍,但是如果数据项减少了50%,可能A算法和B算法速度一样。所以描述算法的速度必须要和数据项的个数联系起来。也就是“大O”表示法,它是一种算法复杂度的相对表示方式,这里我简单介绍一下,后面会根据具体的算法来描述。
60+
前面三点 正确性,可读性和健壮性相信都好理解。对于第四点算法的执行效率和存储量,我们知道比较算法的时候,可能会说“A算法比B算法快两倍”之类的话,但实际上这种说法没有任何意义。因为当数据项个数发生变化时,A算法和B算法的效率比例也会发生变化,比如数据项增加了50%,可能A算法比B算法快三倍,但是如果数据项减少了50%,可能A算法和B算法速度一样。所以描述算法的速度必须要和数据项的个数联系起来。也就是“大O”表示法,它是一种算法复杂度的相对表示方式,这里我简单介绍一下,后面会根据具体的算法来描述。
4261

43-
  相对(relative):你只能比较相同的事物。你不能把一个做算数乘法的算法和排序整数列表的算法进行比较。但是,比较2个算法所做的算术操作(一个做乘法,一个做加法)将会告诉你一些有意义的东西;
62+
相对(relative):你只能比较相同的事物。你不能把一个做算数乘法的算法和排序整数列表的算法进行比较。但是,比较2个算法所做的算术操作(一个做乘法,一个做加法)将会告诉你一些有意义的东西;
4463

45-
  表示(representation):大O(用它最简单的形式)把算法间的比较简化为了一个单一变量。这个变量的选择基于观察或假设。例如,排序算法之间的对比通常是基于比较操作(比较2个结点来决定这2个结点的相对顺序)。这里面就假设了比较操作的计算开销很大。但是,如果比较操作的计算开销不大,而交换操作的计算开销很大,又会怎么样呢?这就改变了先前的比较方式;
64+
表示(representation):大O(用它最简单的形式)把算法间的比较简化为了一个单一变量。这个变量的选择基于观察或假设。例如,排序算法之间的对比通常是基于比较操作(比较2个结点来决定这2个结点的相对顺序)。这里面就假设了比较操作的计算开销很大。但是,如果比较操作的计算开销不大,而交换操作的计算开销很大,又会怎么样呢?这就改变了先前的比较方式;
4665

47-
  复杂度(complexity):如果排序10,000个元素花费了我1秒,那么排序1百万个元素会花多少时间?在这个例子里,复杂度就是相对其他东西的度量结果。
66+
复杂度(complexity):如果排序10,000个元素花费了我1秒,那么排序1百万个元素会花多少时间?在这个例子里,复杂度就是相对其他东西的度量结果。
4867

49-
  然后我们在说说算法的存储量,包括:
68+
然后我们在说说算法的存储量,包括:
5069

51-
  程序本身所占空间;
70+
程序本身所占空间;
5271

53-
  输入数据所占空间;
72+
输入数据所占空间;
5473

55-
  辅助变量所占空间;
74+
辅助变量所占空间;
5675

57-
  一个算法的效率越高越好,而存储量是越低越好。
76+
一个算法的效率越高越好,而存储量是越低越好。
5877

59-
#### 2.**TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?**
78+
#### 2.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
6079

6180
TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java中对函数式编程的支持)。
6281

63-
#### 3.**如何知道二叉树的深度?**
82+
#### 3.如何知道二叉树的深度?
6483

6584
实现二叉树的深度方式有两种,递归以及非递归。
6685

@@ -76,7 +95,7 @@ TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口
7695

7796
树的宽度:在树的深度算法基础上,加一个记录访问过的层节点个数最多的变量max,在访问每层前max与last比较,如果max比较大,max不变,如果max小于last,把last赋值给max;
7897

79-
#### 4.**介绍一下,堆排序的原理是什么?**
98+
#### 4.介绍一下,堆排序的原理是什么?
8099

81100
堆排序就是把最大堆堆顶的最大数取出,将剩余的堆继续调整为最大堆,再次将堆顶的最大数取出,这个过程持续到剩余数只有一个时结束。在堆中定义以下几种操作:
82101

@@ -165,7 +184,7 @@ public class BinarySearchUtils {
165184

166185
详见:https://mp.weixin.qq.com/s/bCH-aU8cKS3uT6PwRYNJtA
167186

168-
#### 10.**如何在一个1到100的整数数组中找到丢失的数字?**
187+
#### 10.如何在一个1到100的整数数组中找到丢失的数字?
169188

170189
如果是丢了一个数字,用个遍历把这些数字累加求和,
171190

@@ -185,13 +204,13 @@ public class BinarySearchUtils {
185204

186205
先排序,并创建一个用来装缺失数的空数组,排好序后遍历,最大的数用101减,其余用后一个值减去前一个值如果差值不是1而是为n,就把被减数分别加1到(n-1)得出的数保存下来就是缺少的数字
187206

188-
#### 11.**请你讲讲LRU算法的实现原理?**
207+
#### 11.请你讲讲LRU算法的实现原理?
189208

190209
①LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也很高”,反过来说“如果数据最近这段时间一直都没有访问,那么将来被访问的概率也会很低”,两种理解是一样的;常用于页面置换算法,为虚拟页式存储管理服务。
191210

192211
②达到这样一种情形的算法是最理想的:每次调换出的页面是所有内存页面中最迟将被使用的;这可以最大限度的推迟页面调换,这种算法,被称为理想页面置换算法。可惜的是,这种算法是无法实现的。 为了尽量减少与理想算法的差距,产生了各种精妙的算法,最近最少使用页面置换算法便是其中一个。LRU 算法的提出,是基于这样一个事实:在前面几条指令中使用频繁的页面很可能在后面的几条指令中频繁使用。反过来说,已经很久没有使用的页面很可能在未来较长的一段时间内不会被用到 。这个,就是著名的局部性原理——比内存速度还要快的cache,也是基于同样的原理运行的。因此,我们只需要在每次调换时,找到最近最少使用的那个页面调出内存。
193212

194-
#### 12.**为什么要设计后缀表达式,有什么好处?**
213+
#### 12.为什么要设计后缀表达式,有什么好处?
195214

196215
后缀表达式又叫逆波兰表达式,逆波兰记法不需要括号来标识操作符的优先级。
197216

@@ -232,7 +251,7 @@ B树的变种,拥有B树的特点
232251
由于非叶节点只保存关键字和指向叶节点的指针,B+树可以容纳更多的关键字,树层数变小,磁盘查询次数更低。
233252
B+树的查询效率比较稳定,查询所有关键字的路径相同。(MySQL索引就提供了B+树的实现方式)
234253

235-
#### 15.**谈一谈,id全局唯一且自增,如何实现?**
254+
#### 15.谈一谈,id全局唯一且自增,如何实现?
236255

237256
SnowFlake雪花算法
238257

@@ -256,4 +275,4 @@ https://blog.csdn.net/Mr_BJL/article/details/88073694
256275

257276
https://blog.csdn.net/chenshiyang0806/article/details/90744039
258277

259-
https://blog.csdn.net/Weixiaohuai/article/details/83188174
278+
https://blog.csdn.net/Weixiaohuai/article/details/83188174

0 commit comments

Comments
 (0)