Skip to content

Commit 6778730

Browse files
committed
add train
1 parent cc86652 commit 6778730

File tree

9 files changed

+466
-53
lines changed

9 files changed

+466
-53
lines changed

.idea/workspace.xml

Lines changed: 175 additions & 49 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@
5555

5656
[桶排序](./algorithms/sort/bucket)
5757

58+
### 训练
5859

60+
#### String
61+
- 字符串反转
5962

6063

6164
#### 参考资料

algorithms/sort/bubble/bubble.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,19 @@ func BubbleSort(arr []int) {
3838
// }
3939
// return arr
4040
//}
41+
42+
//func BubbleSort2(arr []int) {
43+
// l := len(arr)
44+
// for i := 0; i<l; i++ {
45+
// flag := true
46+
// for j:=0;j<l-i-1;j++ {
47+
// if arr[j+1] < arr[j] {
48+
// arr[j+1],arr[j] = arr[j],arr[j+1]
49+
// flag = false
50+
// }
51+
// }
52+
// if flag {
53+
// break
54+
// }
55+
// }
56+
//}

algorithms/sort/bubble/bubble_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ func TestBubbleSort(t *testing.T) {
1414
}
1515
}
1616

17+
1718
func benchmarkBubbleSort(n int, b *testing.B) {
1819
b.StopTimer()
1920
list := utils.GetArrayOfSize(n)
@@ -24,6 +25,7 @@ func benchmarkBubbleSort(n int, b *testing.B) {
2425
}
2526
}
2627

28+
2729
func BenchmarkBubbleSort100(b *testing.B) { benchmarkBubbleSort(100, b) }
2830
func BenchmarkBubbleSort1000(b *testing.B) { benchmarkBubbleSort(1000, b) }
2931
func BenchmarkBubbleSort10000(b *testing.B) { benchmarkBubbleSort(10000, b) }

algorithms/sort/quick/quick.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func QuickSort(arr []int) []int {
1818

1919
func quickSort(arr []int, left, right int) []int {
2020
if left < right {
21-
partitionIndex := partition(arr, left, right)
21+
partitionIndex := partition(arr, left, right)//找分区点
2222
quickSort(arr, left, partitionIndex-1)
2323
quickSort(arr, partitionIndex+1, right)
2424
}
@@ -30,7 +30,7 @@ func partition(arr []int, left, right int) int {
3030
index := pivot + 1
3131

3232
for i := index; i <= right; i++ {
33-
if arr[i] < arr[pivot] { //这里是关键,找到一个比基准大的数和一个比基准小的树数进行交换
33+
if arr[i] < arr[pivot] { //这里是关键,找到一个比基准大的数和一个比基准小的数进行交换
3434
swap(arr, i, index)
3535
index += 1
3636
}

algorithms/sort/quick/quick_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ func TestQuickSort(t *testing.T) {
1313
}
1414
}
1515

16+
1617
func benchmarkQuickSort(n int, b *testing.B) {
1718
b.StopTimer()
1819
list := utils.GetArrayOfSize(n)

data-structures/README.md

Lines changed: 224 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
[概念](https://blog.csdn.net/qq_31196849/article/details/78529724)
44

5+
[c/c++实现](http://www.cnblogs.com/skywang12345/p/3603935.html)
6+
7+
[经典教程](https://www.cnblogs.com/ciyeer/category/1214864.html)
8+
59
[数据结构汇总](https://www.jianshu.com/p/2469a4d9708e)
610

711
[算法时间复杂度的计算](http://univasity.iteye.com/blog/1164707)
812

9-
1013
### 逻辑结构:
1114

1215
具体问题抽象出来的数学模型
@@ -25,6 +28,11 @@
2528
ADT=(D,S, P) D是数据对象 S是D上的关系集 P是对D的基本操作集
2629
类似面向对象程序中的类
2730

31+
### 数据类型
32+
33+
原子类型:整形 浮点型
34+
结构类型:可拆解的类型
35+
2836

2937
### 算法和其5个特性:
3038

@@ -34,17 +42,58 @@ ADT=(D,S, P) D是数据对象 S是D上的关系集 P是对D的基本操作
3442

3543
### 线性表
3644

37-
线性表是n(n>0)个相同类型数据元素构成的有限序列,其中n为线性表的长度
45+
线性表是n(n>=0)个相同类型数据元素构成的有限序列,其中n为线性表的长度
3846

3947
1. 顺序存储(顺序表):数组(连续的存储单元)
4048
2. 链式存储:每个元素(data + next指针,不连续的存储单元,链表不是随机存取结构,只能顺序存取
4149

50+
51+
52+
#### 数组
53+
54+
特点:
55+
56+
- 连续的内存空间和相同类型的数据,基于这2个特点,实现随机访问 O(1),CPU预读对缓存友好
57+
- 插入和删除数据,为了保证连续性,需要做数据搬移,O(n)
58+
4259
#### 链表
4360

61+
特点:零散的内存块
62+
63+
不管链表是不是空,head 指针都会一直指向这个哨兵结点,可以简化编程难度。我们也把这种有哨兵结点的链表叫**带头链表**
64+
65+
4466
1. 单向链表:
4567
2. 循环链表:表中的尾节点指向头节点,形成一个环,操作和线性链表基本一致,没有NULL指针,故终止条件为,是否等于某一个指定的指针
4668
3. 双向链表:双向链表是在单链表的每个结点里再增加一个指向其直接前驱的指针域prior。这样就形成了链表中有两个方向不同的链
4769

70+
#### 跳表
71+
72+
- 为链表添加多级索引的结构,就是跳表,利用了二分查找思想
73+
- 解决链表查找需要遍历全部链表的缺点
74+
75+
#### 散列表
76+
77+
- 散列函数
78+
- 散列冲突:开放寻址法 链表法
79+
- 装载因子: 填入表中的元素个数/散列表的长度
80+
81+
#### 位图(BitMap)
82+
83+
- 特殊的散列表
84+
- 位的映射(数组下表为key,值为bit,1为存在,0为不存在)
85+
- 应用:
86+
1. 快速排序
87+
2. 快速去重
88+
3. 快速查询
89+
90+
#### 布隆过滤器(Bloom Filter)
91+
92+
- 位图的拓展
93+
- 当一个元素被加入集合中时,通过k各散列函数将这个元素映射成一个位数组中的k个点,并将这k个点全部置为1
94+
- 存在误判(不存在一定不存在,存在不一定存在):和哈希函数的个数,位图的大小有关
95+
96+
4897
### 栈和队列
4998

5099
#### 栈(LIFO)
@@ -54,9 +103,182 @@ ADT=(D,S, P) D是数据对象 S是D上的关系集 P是对D的基本操作
54103
##### 栈的存储
55104

56105
顺序栈:利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素
106+
链栈: 采用链表作为存储结构实现的栈。为便于操作,采用带头结点的单链表实现栈,因为栈的插入和删除操作仅限制在表头位置进行,所以链表的表头指针就作为栈顶指针
57107

58108
#### 队列(FIFO)
59109

110+
先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素
111+
112+
顺序队列:
113+
链式队列:
114+
循环队列:
115+
116+
117+
118+
#### 广义表
119+
120+
是由零个或多个原子或子表组成的优先序列,是线性表的推广
121+
122+
广义表中的数据元素可以具有不同的结构,因此,难以用顺序存储结构表示,通常采用链式存储结构,每个数据元素可用一个节点表示。由于广义表中有两种数据元素,因此需要有两种结构的节点——一种是表结点,一种是原子结点
123+
124+
125+
###
126+
127+
Tree:是n(你>=0)个节点的有限集T
128+
129+
结点:表示树中的元素,包括数据项及若干指向其子树的分支
130+
131+
结点的度:结点拥有的子树树
132+
133+
树的度:一棵树中最大的结点度数
134+
135+
深度:从上到下度量,经过的边数
136+
137+
高度:从下到上,经过的最大边数
138+
139+
叶子结点:度为0的结点
140+
141+
树的性质:树中的结点数等于所有结点的度数加1
142+
143+
#### 二叉树
144+
145+
满二叉树:特殊的完全二叉树,特点——每一层上的结点数都是最大结点数
146+
147+
148+
完全二叉树:最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大,**适合用数组存储节省空间,先序遍历**
149+
150+
151+
##### 遍历二叉树(相对根节点)
152+
153+
1. 先序遍历:根节点->左子树->右子树
154+
2. 中序遍历:左子树->根节点->右子数
155+
3. 后序遍历:左子树->右子数->根节点
156+
4. 层次遍历:从上到下,从左到右
157+
158+
#### 二叉查找树
159+
160+
二叉查找树要求,在树中的任意一个节点,左子树值<节点值<右子树值
161+
162+
163+
##### 特性
164+
165+
中序遍历二叉查找树,可以输出有序的数据序列,时间复杂度是O(n)
166+
167+
##### 支持重复数据的二叉查找树
168+
169+
1. 节点存对象,不存值
170+
2. 值相同,放右子树,当要查找数据的时候,遇到值相同的节点,我们并不停止查找操作,只到叶子节点
171+
172+
##### 为什么有散列表还需要二叉查找树
173+
174+
1. 散列表数据无序存储,无法输出有序数据
175+
2. 散列表扩容耗时,有散列冲突,不稳定
176+
3. 散列表构造复杂(散列函数的设计,扩容,缩容,散列冲突)
177+
178+
#### 红黑树
179+
180+
一种近视平衡的二叉查找树,是为解决二叉查找树频繁对数据更新过程中,复杂度退化的问题,性能稳定,O(logn)
181+
182+
##### 为什么工程上喜欢用红黑树而不是AVL树
183+
184+
AVL树每次插入,删除,更新都要调整树,比较复杂,耗时,而红黑树是近似平衡树,不需要每次调整
185+
186+
187+
##### 特点
188+
189+
- 根节点是黑色
190+
- 每个叶子节点都是黑色的空节点(NIL)
191+
- 任何相邻的节点都不能同时为红色
192+
- 每个节点,到其可达的叶子节点的所有路劲,都包含相同的黑色节点
193+
194+
195+
####
196+
197+
- 完全二叉树
198+
- 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点
199+
- 大顶堆和小顶堆
200+
- 插入一个数据的时候,我们把新插入的数据放到数组的最后,然后从从下往上堆化;删除堆顶数据的时候,我们把数组中的最后一个元素放到堆顶,然后从上往下堆化。这两个操作时间复杂度都是O(logn)
201+
202+
##### 为什么堆排序没有快速排序快
203+
204+
- 堆排序数据访问的方式没有快速排序友好,跳着访问,对cpu不友好
205+
- 对于同样的数据,在排序过程中,堆排序算法的数据交换次数要多于快速排序
206+
207+
##### 堆的应用
208+
209+
1. 优先级队列(如:高性能定时器)
210+
2. 求TopK问题(静态数据:维护一个K的小顶堆,依次比较[O(nlogK)],动态数据类似)
211+
3. 求动态数据中位数(维护一个大顶堆,一个小顶堆,而且小顶堆中的元素都大于大顶堆中的元素,通过动态调整堆大小来满足数据平衡)
212+
213+
#### Trie树 也叫“字典树
214+
215+
1. 就是利用字符串之间的公共前缀,将重复的前缀合并在一起
216+
2. 主要操作:构造一个Trie树 在Trie树中查找一个字符串
217+
3. Trie树不如红黑树和散列表适合精确匹配,它更加**适合前缀匹配**
218+
4. 比较耗内存
219+
5. 时间复杂度是 O(k),k 表示要匹配的字符串的长度
220+
6. 应用场景:字符串的字符集不能太大,前缀重合比较多
221+
222+
223+
224+
###
225+
226+
在图形结构中,结点之间关系可以是任意的,图中任意两个数据元素之间都可能相关
227+
228+
1. 有向图
229+
2. 无向图
230+
231+
#### 图的存储结构
232+
##### 邻接矩阵
233+
234+
邻接矩阵是表示顶点之间相邻关系的矩阵
235+
236+
1. 优点:容易实现图的操作,如判断顶点间是否有边(弧)
237+
2. 缺点: 对稀疏图浪费空间
238+
239+
##### 邻接表
240+
241+
一种顺序分配与链式分配相结合的存储方法。它包括两部分:一部分是单链表,用来存放边的信息;另一部分是数组,主要用来存放顶点本身的数据信息
242+
243+
1. 优点:空间利用率高,容易找顶点的邻接点
244+
2. 缺点:判断2顶点间是否有弧,需搜索2结点对应的单链表
245+
246+
##### 逆领接表
247+
248+
249+
为了解决领接表的缺点,查找入度需要遍历所有的顶点对应的边
250+
251+
##### 十字链表
252+
253+
十字链表是有向图的另一种链式存储结构。可以看成是将有向图的邻接表和逆邻接表结合起来得到的一种链表。在十字链表中,每条弧和每个顶点分别对应着一个结点
254+
255+
##### 邻接多重表
256+
257+
邻接多重表是无向图的另一种链式存储结构。邻接多重表和十字链表一样,每条边和每个顶点分别对应着一个结点
258+
259+
#### 图的遍历
260+
261+
##### 图的暴力搜索
262+
263+
时间复杂度都是 O(E),空间复杂度是 O(V)
264+
265+
1. 深度优先搜索(DFS)
266+
267+
- 回溯思想
268+
- 借助栈来实现
269+
270+
2. 广度优先搜索(WFS)
271+
272+
- 地毯式层层推进
273+
- 借助队列来实现
274+
275+
## B+ tree vs LSM tree
276+
277+
[比较](http://www.cnblogs.com/fxjwind/archive/2012/06/09/2543357.html)
278+
279+
280+
281+
60282

61283

62284

train/string/reverse.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package string
2+
3+
4+
//字符串反转(三步反转法)
5+
//将 abcdef 反转成 defabc //1.abc->cba 2.def->fed 3.cbafed->defabc
6+
func LeftRotateStritog(s string,m,n int) string {
7+
_s := []byte(s)
8+
reverseString(_s,0,m-1)
9+
reverseString(_s,m,n-1)
10+
reverseString(_s,0,n-1)
11+
return string(_s)
12+
}
13+
14+
func reverseString(s []byte, from,to int) {
15+
for from < to {
16+
s[from],s[to] = s[to],s[from]
17+
from++
18+
to--
19+
}
20+
}

train/string/reverse_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package string
2+
3+
import (
4+
"github.com/stretchr/testify/assert"
5+
"testing"
6+
)
7+
8+
var (
9+
testData = []struct{
10+
s string
11+
_s string
12+
m,n int
13+
}{
14+
{"abcdef","defabc",3,6},
15+
{"12345678","45612378",3,6},
16+
{"gqdvf","qdvfg",1,5},
17+
}
18+
)
19+
func TestLeftRotateStritog(t *testing.T) {
20+
for _,ts := range testData {
21+
assert.Equal(t,ts._s,LeftRotateStritog(ts.s,ts.m,ts.n))
22+
}
23+
}

0 commit comments

Comments
 (0)