Skip to content

Commit 23f7f3e

Browse files
author
ningfeng
committed
增加锚点 +
1 parent 34732a3 commit 23f7f3e

File tree

6 files changed

+148
-107
lines changed

6 files changed

+148
-107
lines changed

docs/02.md

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
- [1 链表、栈、队列、递归、哈希](#1--------------)
2-
* [1.1 链表](#11---)
3-
+ [1.1.1 单向链表](#111-----)
4-
+ [1.1.2 双向链表](#112-----)
5-
+ [1.1.3 单双链表简单练习](#113---------)
6-
* [1.2 栈、队列](#12-----)
7-
* [1.3 栈、队列常见面试题](#13----------)
8-
* [1.4 递归](#14---)
9-
+ [1.4.1 递归行为的时间复杂度](#141-----------)
10-
* [1.5 哈希表HashMap、HashSet](#15----hashmap-hashset)
11-
* [1.6 顺序表 TreeMap、TreeSet](#16-----treemap-treeset)
12-
13-
# 1 链表、栈、队列、递归、哈希
14-
15-
## 1.1 链表
16-
17-
### 1.1.1 单向链表
1+
- [1 链表、栈、队列、递归、哈希](#1)
2+
* [1.1 链表](#11)
3+
+ [1.1.1 单向链表](#111)
4+
+ [1.1.2 双向链表](#112)
5+
+ [1.1.3 单双链表简单练习](#113)
6+
* [1.2 栈、队列](#12)
7+
* [1.3 栈、队列常见面试题](#13)
8+
* [1.4 递归](#14)
9+
+ [1.4.1 递归行为的时间复杂度](#141)
10+
* [1.5 哈希表HashMap、HashSet](#15)
11+
* [1.6 顺序表 TreeMap、TreeSet](#16)
12+
13+
<h1 id='1'>1 链表、栈、队列、递归、哈希</h1>
14+
15+
<h2 id='11'>1.1 链表</h2>
16+
17+
<h3 id='111'>1.1.1 单向链表</h3>
18+
1819
> 单向链表的节点结构(可以实现成泛型) :
1920
2021
```Java
@@ -28,7 +29,8 @@
2829

2930
}
3031
```
31-
### 1.1.2 双向链表
32+
33+
<h3 id='112'>1.1.2 双向链表</h3>
3234

3335
> 双向链表的节点结构(可以实现成功泛型):
3436
@@ -44,7 +46,7 @@
4446
}
4547
```
4648

47-
### 1.1.3 单双链表简单练习
49+
<h3 id='113'>1.1.3 单双链表简单练习</h3>
4850

4951
1. 单链表和双链表如何反转
5052

@@ -302,7 +304,9 @@ public class Code02_DeleteGivenValue {
302304

303305
> Tips: Java中也有可能产生内存泄漏,与CPP不同,CPP的内存泄漏有可能是我们开辟了内存空间忘记释放。而Java的内存泄漏大可能是程序中的变量的生存周期引起的,如果该程序是一个类似定时任务的7*24小时不间断运行,那么申请的变量(数据结构)就有可能不会被及时释放。如果不注意往里面添加一些不必要的变量,这些变量就是内存泄漏
304306
305-
## 1.2 栈、队列
307+
308+
<h2 id='12'>1.2 栈、队列</h2>
309+
306310
1. 逻辑概念
307311

308312
>栈:数据先进后出,犹如弹夹
@@ -567,7 +571,7 @@ public class Code04_RingArray {
567571
}
568572
```
569573

570-
## 1.3 栈、队列常见面试题
574+
<h2 id='13'>1.3 栈、队列常见面试题</h2>
571575

572576
一、实现一个特殊的栈,在基本功能的基础上,再实现返回栈中最小元素的功能更
573577

@@ -856,7 +860,7 @@ public class Code07_TwoQueueImplementStack {
856860
}
857861
```
858862

859-
## 1.4 递归
863+
<h2 id='14'>1.4 递归</h2>
860864

861865
1、从思想上理解递归
862866

@@ -900,7 +904,7 @@ public class Code08_GetMax {
900904

901905
> 递归在系统中是怎么实现的?递归实际上利用的是系统栈来实现的。保存当前调用现场,去执行子问题,子问题的返回作为现场的需要的参数填充,最终构建还原栈顶的现场,返回。所以递归行为不是玄学,任何递归都可以改为非递归实现,我们自己压栈用迭代等实现就行
902906
903-
### 1.4.1 递归行为的时间复杂度
907+
<h3 id='141'>1.4.1 递归行为的时间复杂度</h3>>
904908

905909
> 对于满足
906910
@@ -932,7 +936,7 @@ logb^a == d => O(N^d * logN)
932936

933937
那么上述问题的a=2, b=2,d=0,满足第一条,递归时间复杂度为:O(N)
934938

935-
## 1.5 哈希表HashMap、HashSet
939+
<h2 id='15'>1.5 哈希表HashMap、HashSet</h2>>
936940

937941
> Hash表的增删改查,在使用的时候,一律认为时间复杂度是O(1)的
938942
@@ -942,7 +946,8 @@ logb^a == d => O(N^d * logN)
942946

943947
==但是在Hash表中,即使是包装类型的key,我们也一律按值传递,例如Hash<Integer,String>如果我们put相同的key的值,那么不会产生两个值相等的key而是覆盖操作。但是Hash表并不是一直是按值传递的,只是针对包装类型,如果是我们自定义的引用类型,那么仍然按引用传递==
944948

945-
## 1.6 顺序表 TreeMap、TreeSet
949+
<h2 id='16'>1.6 顺序表 TreeMap、TreeSet</h2>>
950+
946951

947952
> 顺序表比哈希表功能多,但是顺序表的很多操作时间复杂度是O(logN)
948953

docs/03.md

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
- [1 归并排序、随机快排](#1----------)
2-
* [1.1 归并排序](#11-----)
3-
+ [1.1.1 递归思路:](#111------)
4-
+ [1.1.2 非递归思路](#112------)
5-
+ [1.1.3 归并排序时间复杂度](#113----------)
6-
+ [1.1.4 归并面试题](#114------)
7-
* [1.2 快排](#12---)
8-
+ [1.2.1 Partion过程](#121-partion--)
9-
+ [1.2.2 快排1.0:每次partion搞定一个位置](#122---10---partion------)
10-
+ [1.2.3 快排2.0:每次partion搞定一批位置](#123---20---partion------)
11-
+ [1.2.4 快排3.0:随机位置作为num标记位](#124---30-------num---)
12-
+ [1.2.5 快排的时间复杂度与空间复杂度](#125---------------)
13-
14-
# 1 归并排序、随机快排
15-
16-
## 1.1 归并排序
1+
- [1 归并排序、随机快排](#1)
2+
* [1.1 归并排序](#11)
3+
+ [1.1.1 递归思路:](#111)
4+
+ [1.1.2 非递归思路](#112)
5+
+ [1.1.3 归并排序时间复杂度](#113)
6+
+ [1.1.4 归并面试题](#114)
7+
* [1.2 快排](#12)
8+
+ [1.2.1 Partion过程](#121)
9+
+ [1.2.2 快排1.0:每次partion搞定一个位置](#122)
10+
+ [1.2.3 快排2.0:每次partion搞定一批位置](#123)
11+
+ [1.2.4 快排3.0:随机位置作为num标记位](#124)
12+
+ [1.2.5 快排的时间复杂度与空间复杂度](#125)
13+
14+
<h1 id='1'>1 归并排序、随机快排</h1>>
15+
16+
<h2 id='11'>1.1 归并排序</h2>>
1717

1818
1、 整体是递归的,左边排好序右边排好序,最后merge让整体有序,merge过程需要申请和被排序数组等长度的辅助空间
1919

@@ -23,7 +23,7 @@
2323

2424
4、 归并排序可改为非递归实现
2525

26-
### 1.1.1 递归思路:
26+
<h3 id='111'>1.1.1 递归思路:</h3>>
2727

2828
> 主函数希望一个数组的0~3位置排序f(arr, 0, 3)
2929
@@ -35,7 +35,7 @@
3535
3636
> f(arr, 0, 3)需要merge f(arr, 0, 1)和f(arr, 2, 3)此时f(arr, 0, 1)和f(arr, 2, 3)已经有序merge后copy到原数组的0到3位置。于是f(arr, 0, 3)整体有序
3737
38-
### 1.1.2 非递归思路
38+
<h3 id='112'>1.1.2 非递归思路</h3>>
3939

4040
> 对于一个给定长度为n的数组arr,我们希望arr有序
4141
@@ -209,7 +209,7 @@ public class Code01_MergeSort {
209209
}
210210
```
211211

212-
### 1.1.3 归并排序时间复杂度
212+
<h3 id='113'>1.1.3 归并排序时间复杂度</h3>>
213213

214214
> 递归复杂度计算,用master公式带入,子问题规模N/2,调用2次,除了递归之外的时间复杂度为merge的时间复杂度,为O(N)。a=2,b=2,d=1满足master第一条logb^a == d规则
215215
@@ -223,7 +223,7 @@ T(N) = 2T(N/2) + O(N) => O(N*logN)
223223

224224
Tips: 为什么选择,冒泡,插入排序的时间复杂度为O(N^2)而归并排序时间复杂度为O(NlogN),因为选择,冒泡,插入排序的每个元素浪费了大量的比较行为N次。而归并没有浪费比较行为,每次比较的结果有序后都会保存下来,最终merge
225225

226-
### 1.1.4 归并面试题
226+
<h3 id='114'>1.1.4 归并面试题</h3>>
227227

228228
1、在一个数组中,一个数左边比它小的数的总和,叫做小和,所有数的小和累加起来,叫做数组的小和。求数组的小和。例如[1, 3, 4, 2, 5]
229229

@@ -389,9 +389,9 @@ public class Code02_SmallSum {
389389

390390
> 什么样的题目以后可以借助归并排序:纠结每个数右边(左边)有多少个数比自身大,比自身小等。求这种数的数量等等
391391
392-
## 1.2 快排
392+
<h2 id='12'>1.2 快排</h2>>
393393

394-
### 1.2.1 Partion过程
394+
<h3 id='121'>1.2.1 Partion过程</h3>>
395395

396396
> 给定一个数组arr,和一个整数num。请把小于等于num的数放在数组的左边,大于num的数放在数组的右边(不要求有序)。要求额外空间复杂度为O(1),时间复杂度为O(N)。例如[5,3,7,2,3,4,1],num=3,把小于等于3的放在左边,大于3的放在右边
397397
@@ -413,18 +413,18 @@ public class Code02_SmallSum {
413413

414414
4、i和大于区域的边界相遇,停止操作
415415

416-
### 1.2.2 快排1.0:每次partion搞定一个位置
416+
<h3 id='122'>1.2.2 快排1.0:每次partion搞定一个位置</h3>>
417417

418418
思路:在给定数组上做partion,选定数组最右侧的位置上的数作为num,小于num的放在该数组的左边,大于num的放在该数组的右边。完成之后,把该数组最右侧的数组num,交换到大于num区域的第一个位置,确保了交换后的num是小于等于区域的最后一个数(该数直至最后可以保持当前位置不变,属于已经排好序的数),把该num左侧和右侧的数分别进行同样的partion操作(递归)。相当于每次partion搞定一个数的位置,代码实现quickSort1
419419

420420

421-
### 1.2.3 快排2.0:每次partion搞定一批位置
421+
<h3 id='123'>1.2.3 快排2.0:每次partion搞定一批位置</h3>>
422422

423423
思路:借助荷兰国旗问题的思路,把arr进行partion,把小于num的数放左边,等于放中间,大于放右边。递归时把小于num的区域和大于num的区域做递归,等于num的区域不做处理。相当于每次partion搞定一批数,与标记为相等的数。代码实现quickSort2
424424

425425
> 第一版和第二版的快排时间复杂度相同O(N^2):用最差情况来评估,本身有序,每次partion只搞定了一个数是自身,进行了N次partion
426426
427-
### 1.2.4 快排3.0:随机位置作为num标记位
427+
<h3 id='124'>1.2.4 快排3.0:随机位置作为num标记位</h3>>
428428

429429
==随机选一个位置i,让arr[i]和arr[R]交换,再用=arr[R]作为标记位。剩下的所有过程跟快排2.0一样。即为最经典的快排,时间复杂度为O(NlogN)==
430430

@@ -438,7 +438,7 @@ T(N) = T((1/3)N) + T((2/3)N) + O(N)
438438

439439
> 对于这个递归表达式,master公式是解不了的,master公式只能解决子问题规模一样的递归。对于这个递归,算法导论上给出了计算方法,大致思路为假设一个复杂度,看这个公式是否收敛于这个复杂度的方式,比较麻烦
440440
441-
### 1.2.5 快排的时间复杂度与空间复杂度
441+
<h3 id='125'>1.2.5 快排的时间复杂度与空间复杂度</h3>>
442442

443443
> 时间复杂度参考上文每种的复杂度
444444

docs/04.md

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
- [1 比较器与堆](#1------)
2-
* [1.1 堆结构](#11----)
3-
+ [1.1.1 完全二叉树结构](#111--------)
4-
+ [1.1.2 数组实现堆](#112------)
5-
+ [1.1.3 大根堆与小根堆](#113--------)
6-
+ [1.1.4 构建堆](#114----)
7-
+ [1.1.5 堆排序](#115----)
8-
+ [1.1.6 语言、系统提供的堆和手写堆的选择](#116-----------------)
9-
- [1.1.6.1 系统实现的堆](#1161-------)
10-
- [1.1.6.2 系统堆和手写堆选择](#1162----------)
11-
* [1.2 比较器](#12----)
1+
- [1 比较器与堆](#1)
2+
* [1.1 堆结构](#11)
3+
+ [1.1.1 完全二叉树结构](#111)
4+
+ [1.1.2 数组实现堆](#112)
5+
+ [1.1.3 大根堆与小根堆](#113)
6+
+ [1.1.4 构建堆](#114)
7+
+ [1.1.5 堆排序](#115)
8+
+ [1.1.6 语言、系统提供的堆和手写堆的选择](#116)
9+
- [1.1.6.1 系统实现的堆](#1161)
10+
- [1.1.6.2 系统堆和手写堆选择](#1162)
11+
* [1.2 比较器](#12)
1212

13-
# 1 比较器与堆
13+
<h1 id='1'>1 比较器与堆</h1>>
1414

15-
## 1.1 堆结构
15+
<h2 id='11'>1.1 堆结构</h2>>
1616

17-
### 1.1.1 完全二叉树结构
17+
<h3 id='111'>1.1.1 完全二叉树结构</h3>>
1818

1919
> 完全二叉树结构:要么本层是满的,要么先满左边的,以下都是完全二叉树
2020
@@ -35,7 +35,7 @@ B-->E
3535
C-->F
3636
```
3737

38-
### 1.1.2 数组实现堆
38+
<h3 id='112'>1.1.2 数组实现堆</h3>>
3939

4040
- 堆结构就是用数组实现的完全二叉树结构
4141

@@ -79,7 +79,8 @@ rchild = 2*i + 1 <==> (i << 1) | 1
7979
```math
8080
parent = i / 2 <==> i >> 1
8181
```
82-
### 1.1.3 大根堆与小根堆
82+
83+
<h3 id='113'>1.1.3 大根堆与小根堆</h3>>
8384

8485
- 完全二叉树中如果每棵子树的最大值都在顶部就是大根堆
8586

@@ -88,8 +89,7 @@ parent = i / 2 <==> i >> 1
8889
==我们认为堆就是大根堆或者小根堆,既不是大根堆也不是小根堆的完全二叉树只是完全二叉树,不能称之为堆==
8990

9091

91-
92-
### 1.1.4 构建堆
92+
<h3 id='114'>1.1.4 构建堆</h3>
9393

9494
- 堆结构的heapInsert与heapify操作
9595

@@ -282,7 +282,7 @@ public class Code02_Heap01 {
282282
```
283283

284284

285-
### 1.1.5 堆排序
285+
<h3 id='115'>1.1.5 堆排序</h3>>
286286

287287
1. 对于用户给的所有数据,我们先让其构建成为大根堆
288288
2. 对于0到N-1位置的数,我们依次让N-1位置的数和0位置的数(全局最大值)交换,此时全局最大值来到了数组最大位置,堆大小减一,再heapify调整成大根堆。再用N-2位置的数和调整后的0位置的数交换,相同操作。直至0位置和0位置交换。每次heapify为logN,交换调整了N次
@@ -475,9 +475,9 @@ T(N) = N + \frac{N}{2} + \frac{N}{4} + \frac{N}{8} + ...
475475
476476
```
477477

478-
### 1.1.6 语言、系统提供的堆和手写堆的选择
478+
<h3 id='116'>1.1.6 语言、系统提供的堆和手写堆的选择</h3>>
479479

480-
#### 1.1.6.1 系统实现的堆
480+
<h4 id='1161'>1.1.6.1 系统实现的堆</h4>>
481481

482482
> 系统实现的堆实质上就是优先级队列,虽然名称叫优先级队列,底层就是堆实现的。默认是小根堆,我们可以自定义比较器把它改为大根堆
483483
@@ -660,7 +660,7 @@ public class Code05_SortArrayDistanceLessK {
660660

661661
> 时间复杂度O(NlogK)
662662
663-
#### 1.1.6.2 系统堆和手写堆选择
663+
<h4 id='1162'>1.1.6.2 系统堆和手写堆选择</h4>>
664664

665665
> 使用系统提供的堆:如果我们只是要依次拿最大值,那么做成大根堆,如果我们要最小值我们把堆结构做成小根堆。就是简单的我们添加值,拿值,我们就选择系统提供的堆
666666
@@ -924,7 +924,7 @@ public class Code03_Heap02 {
924924
}
925925
```
926926

927-
## 1.2 比较器
927+
<h2 id='12'>1.2 比较器</h2>>
928928

929929
1、比较器的实质就是重载比较运算符
930930

0 commit comments

Comments
 (0)