Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
hunterhug committed Dec 9, 2019
1 parent c322eb8 commit 2bcea86
Show file tree
Hide file tree
Showing 45 changed files with 386 additions and 89 deletions.
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.vscode/
.idea/
.git
.DS_Store
.gitignore
_book/
node_modules/
package-lock.json
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
.idea/*
_book/
node_modules/
.vscode/
.idea/
.DS_Store
package-lock.json
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM hunterhug/gitbook:latest AS gitbookk
WORKDIR /srv/gitbook
COPY . /srv/gitbook/
RUN gitbook build . --log=debug --debug

## main build
FROM nginx:1.15 AS prod
WORKDIR /usr/share/nginx/html
COPY --from=gitbookk /srv/gitbook/_book /usr/share/nginx/html
133 changes: 45 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,45 @@
# GoAlgorithm

# 前言

Golang是谷歌推出的一门静态开发语言, 此仓库尝试Go实现各种数据结构和算法.见算法[可视化](https://www.cs.usfca.edu/~galles/visualization/Algorithms.html)

算法示例:

```
--sort
----quicksort 快速排序
--heaplike
----heaps 最小堆
----leftist 左偏树
--other
----mala 马拉松算法(最长回文子串)
```

## 排序

### 快速排序

```
1. 定义
快速排序由C. A. R. Hoare在1962年提出。快速排序是对冒泡排序的一种改进,采用了一种分治的策略。
2. 基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
3. 步骤
a. 先从数列中取出一个数作为基准数。
b. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
c. 再对左右区间重复第二步,直到各区间只有一个数。
```

### 堆排序

使用优先队列-最小/最大堆可实现。

## 优先队列

优先队列是一种能完成以下任务的队列:插入一个数值,取出最小的数值(获取数值,并且删除)。优先队列可以用二叉树来实现,我们称这种为二叉堆。

### 最小堆

最小堆是二叉堆的一种,是一颗完全二叉树(一种平衡树), 其特点是父节点的键值总是小于或者等于子节点。

```
实现细节(两个操作):
push:向堆中插入数据时,首先在堆的末尾插入数据,然后不断向上提升,直到没有大小颠倒时。
pop:从堆中删除最小值时首先把最后一个值复制到根节点上,并且删除最后一个数值。然后不断向下交换, 直到没有大小颠倒为止。在向下交换过程中,如果有两个子儿子都小于自己,就选择较小的
插入时间复杂度O(logN),删除时间复杂度O(logN),两个二叉堆合并时间复杂性O(NlogN).
```

最大堆同理。可用此结构实现堆排序算法。

## 左偏树

最小堆/最大堆如果两个堆进行合并,时间复杂度较高,左偏树是可合并的二叉堆,首先满足所有的堆的性质,其外,各种操作时间复杂度都是O(logN)。

```
左偏树的树节点需要保存的信息有:
1.左右子树节点编号
2.此节点到有空子结点的最短距离len(空子节点的节点,就是子节点数不足2个的节点)
3.自身权值
左偏就是每个节点的左子节点的len不小于右子节点的len(但并不代表左子节点数一定不小于右子节点数),那么可知左偏树中一个节点的距离就是右儿子距离+1(或没有右儿子),且左右子树都是左偏树。
合并树A和树B的操作方法如下:
1.如果A或B有一个是空树,返回另一个。
2.如果A的优先级比B低,交换A,B。(确保左堆根节点小于右堆根节点)
3.递归处理,将B和A的右子树合并。(B,Right(A)递归处理)
4.如果合并过后A的右儿子距离大于A的左儿子,交换A的左右儿子。(确保左儿子距离大于右儿子)
5.更新A的距离。
```

左偏树合并操作合并的是两棵左偏树,对于堆的插入,就是合并一棵树和一个节点,对于堆的删除,就是合并根的两棵子树。

## 最长回文子串

使用马拉松算法,进行巧妙地计算,得到回文子串。
# 算法分析:Golang实现

## 前言

数据结构和算法在计算机科学里,有非常重要的地位。此仓库尝试使用 Golang 来实现各种数据结构和算法,并且进行分析。

中文版为该仓库,英文版请见分支 `en`

## 目录

* [目录](README.md)
* [基础知识](basic/README.md)
* [复杂度及渐进符号](basic/dregee.md)
* [复杂度主方法](basic/master_method.md)
* [常见数据结构及算法](basic/README.md)
* [栈和队列](algorithm/stack_queues.md)
* [排序算法](algorithm/sort.md)
* [冒泡排序](algorithm/sort/bubble_sort.md)
* [选择排序](algorithm/sort/select_sort.md)
* [插入排序](algorithm/sort/insert_sort.md)
* [希尔排序](algorithm/sort/shell_sort.md)
* [归并排序](algorithm/sort/merge_sort.md)
* [快速排序](algorithm/sort/quick_sort.md)
* [优先队列及堆排序](algorithm/heaplike/heaps.md)
* [查找算法](algorithm/search.md)
* [散列查找:拉链法](algorithm/search/hash_find.md)
* [树及二叉查找树](algorithm/search/bs_tree.md)
* [AVL树和红黑树](algorithm/search/avl_rb_tree.md)
* [B树及B+树](algorithm/search/b_tree.md)
* [图算法](algorithm/graph.md)
* [深度搜索和广度搜索](algorithm/graph/search.md)
* [求点到点最短路径:Dijkstra算法](algorithm/graph/dijkstra.md)
* [求全部点最短路径:Floyd算法](algorithm/graph/floyd.md)
* [最小生成树:Prim和Kruskal算法](algorithm/graph/minicost_span_tree.md)
* [不常见算法](algorithm/other.md)
* [堆合并:左偏树](algorithm/heaplike/leftist.md)
* [编程智商题](acm/README.md)
* [求最长回文子串](acm/mala.md)
* [回溯法:八皇后](acm/queen.md)
* [文档部署](doc/install.md)
* [参考](basic/refer.md)

## 作者寄语

学而不思则罔,思而不学则殆。
34 changes: 34 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Summary

* [目录](README.md)
* [基础知识](basic/README.md)
* [复杂度及渐进符号](basic/dregee.md)
* [复杂度主方法](basic/master_method.md)
* [常见数据结构及算法](basic/README.md)
* [栈和队列](algorithm/stack_queues.md)
* [排序算法](algorithm/sort.md)
* [冒泡排序](algorithm/sort/bubble_sort.md)
* [选择排序](algorithm/sort/select_sort.md)
* [插入排序](algorithm/sort/insert_sort.md)
* [希尔排序](algorithm/sort/shell_sort.md)
* [归并排序](algorithm/sort/merge_sort.md)
* [快速排序](algorithm/sort/quick_sort.md)
* [优先队列及堆排序](algorithm/heaplike/heaps.md)
* [查找算法](algorithm/search.md)
* [散列查找:拉链法](algorithm/search/hash_find.md)
* [树及二叉查找树](algorithm/search/bs_tree.md)
* [AVL树和红黑树](algorithm/search/avl_rb_tree.md)
* [B树及B+树](algorithm/search/b_tree.md)
* [图算法](algorithm/graph.md)
* [深度搜索和广度搜索](algorithm/graph/search.md)
* [求点到点最短路径:Dijkstra算法](algorithm/graph/dijkstra.md)
* [求全部点最短路径:Floyd算法](algorithm/graph/floyd.md)
* [最小生成树:Prim和Kruskal算法](algorithm/graph/minicost_span_tree.md)
* [不常见算法](algorithm/other.md)
* [堆合并:左偏树](algorithm/heaplike/leftist.md)
* [编程智商题](acm/README.md)
* [求最长回文子串](acm/mala.md)
* [回溯法:八皇后](acm/queen.md)
* [文档部署](doc/install.md)
* [参考](basic/refer.md)

2 changes: 2 additions & 0 deletions acm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 编程智商题

3 changes: 3 additions & 0 deletions acm/mala.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 最长回文子串

使用马拉松算法,进行巧妙地计算,得到回文子串。
File renamed without changes.
2 changes: 2 additions & 0 deletions acm/queen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 回溯法:八皇后

2 changes: 2 additions & 0 deletions algorithm/graph.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 图算法

2 changes: 2 additions & 0 deletions algorithm/graph/dijkstra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 求点到点最短路径:Dijkstra算法

2 changes: 2 additions & 0 deletions algorithm/graph/floyd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 求全部点最短路径:Floyd算法

2 changes: 2 additions & 0 deletions algorithm/graph/minicost_span_tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 最小生成树:Prim和Kruskal算法

2 changes: 2 additions & 0 deletions algorithm/graph/search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 深度搜索和广度搜索

22 changes: 22 additions & 0 deletions algorithm/heaplike/heaps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# 堆排序

使用优先队列-最小/最大堆可实现。

## 优先队列

优先队列是一种能完成以下任务的队列:插入一个数值,取出最小的数值(获取数值,并且删除)。优先队列可以用二叉树来实现,我们称这种为二叉堆。

### 最小堆

最小堆是二叉堆的一种,是一颗完全二叉树(一种平衡树), 其特点是父节点的键值总是小于或者等于子节点。

```
实现细节(两个操作):
push:向堆中插入数据时,首先在堆的末尾插入数据,然后不断向上提升,直到没有大小颠倒时。
pop:从堆中删除最小值时首先把最后一个值复制到根节点上,并且删除最后一个数值。然后不断向下交换, 直到没有大小颠倒为止。在向下交换过程中,如果有两个子儿子都小于自己,就选择较小的
插入时间复杂度O(logN),删除时间复杂度O(logN),两个二叉堆合并时间复杂性O(NlogN).
```

最大堆同理。可用此结构实现堆排序算法。
File renamed without changes.
File renamed without changes.
24 changes: 24 additions & 0 deletions algorithm/heaplike/leftist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 左偏树

最小堆/最大堆如果两个堆进行合并,时间复杂度较高,左偏树是可合并的二叉堆,首先满足所有的堆的性质,其外,各种操作时间复杂度都是O(logN)。

```
左偏树的树节点需要保存的信息有:
1.左右子树节点编号
2.此节点到有空子结点的最短距离len(空子节点的节点,就是子节点数不足2个的节点)
3.自身权值
左偏就是每个节点的左子节点的len不小于右子节点的len(但并不代表左子节点数一定不小于右子节点数),那么可知左偏树中一个节点的距离就是右儿子距离+1(或没有右儿子),且左右子树都是左偏树。
合并树A和树B的操作方法如下:
1.如果A或B有一个是空树,返回另一个。
2.如果A的优先级比B低,交换A,B。(确保左堆根节点小于右堆根节点)
3.递归处理,将B和A的右子树合并。(B,Right(A)递归处理)
4.如果合并过后A的右儿子距离大于A的左儿子,交换A的左右儿子。(确保左儿子距离大于右儿子)
5.更新A的距离。
```

左偏树合并操作合并的是两棵左偏树,对于堆的插入,就是合并一棵树和一个节点,对于堆的删除,就是合并根的两棵子树。
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions algorithm/other.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 不常见算法

2 changes: 2 additions & 0 deletions algorithm/search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 查找算法

2 changes: 2 additions & 0 deletions algorithm/search/avl_rb_tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# AVL树和红黑树

2 changes: 2 additions & 0 deletions algorithm/search/b_tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# B树及B+树

2 changes: 2 additions & 0 deletions algorithm/search/bs_tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 树及二叉查找树

2 changes: 2 additions & 0 deletions algorithm/search/hash_find.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 散列查找:拉链法

2 changes: 2 additions & 0 deletions algorithm/sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 排序算法

2 changes: 2 additions & 0 deletions algorithm/sort/bubble_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 冒泡排序

2 changes: 2 additions & 0 deletions algorithm/sort/insert_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 插入排序

2 changes: 2 additions & 0 deletions algorithm/sort/merge_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 归并排序

14 changes: 14 additions & 0 deletions algorithm/sort/quick_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# 快速排序

```
1. 定义
快速排序由C. A. R. Hoare在1962年提出。快速排序是对冒泡排序的一种改进,采用了一种分治的策略。
2. 基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
3. 步骤
a. 先从数列中取出一个数作为基准数。
b. 分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
c. 再对左右区间重复第二步,直到各区间只有一个数。
```
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions algorithm/sort/select_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 选择排序

2 changes: 2 additions & 0 deletions algorithm/sort/shell_sort.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 希尔排序

2 changes: 2 additions & 0 deletions algorithm/stack_queues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 栈和队列

55 changes: 55 additions & 0 deletions basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# 基础知识

## 什么是算法

计算机,顾名思义是用来计算的机器。

计算机接收一个输入指令,然后进行一个过程处理,最后输出计算的结果。

这种输入-过程处理-输出,用人类的行为模式,很容易理解,比如妈妈让小明去打酱油,打酱油的命令是输入,小明发现小区周边有5家店有酱油出售,娟娟超市是离家最近的,而子龙杂货店虽然离得最远,但酱油很便宜。小明为了省钱,跑到最远的子龙杂货店买了酱油,然后顺利回到了家,交给了妈妈。买酱油的过程就是处理,而给妈妈的酱油是输出。

小明为什么不去最近的娟娟超市,而去了最远的子龙杂货店,这是小明脑袋里思考后产生的最佳方案。当然,现在买酱油可以通过外卖软件,小明可以打开美团,搜索关键字:酱油,然后点击筛选,离家最近的和最便宜的,然后选择最便宜的下单。

买酱油的过程 = 美团下单的过程。

人类在几千年的演化中,会进行数字运算了,会思考利益权衡了,然后造了机器,将自己的行为模式,赋予了机器,解放了自身。如果人类真正了解人脑神经元的信息传递过程,甚至可能造出有自我意识的机器,但这种场景仍然只能在科幻电影中看到。

所以,这个逻辑过程,或行为模式,在计算机里面映射的是算法。

最后,在计算机科学中,所有的算法都是人定义的规则,这些规则都是死的,所以学习起来是很容易的。

## 什么是数据结构

数据结构,顾名思义就是存放数据的结构,也可以认为是存放数据的容器。比如,你要找出1000个数字中的最大值,首先你要将1000个数字记在某些卡片上,然后对卡片进行排序。

数据结构在计算机中,主要是用来实现各种算法的基础,当然数据结构本身也是算法的一部分。

基本的数据结构有:栈和队列,树和图,而这些数据结构的实现由数组和链表来实现。在每种编程语言中,数组作为基本数据类型提供,链表呢, `C、C++` 是用指针来实现的,`Java` 是用类来实现的,而 `Golang` 是用结构体引用来实现。

在一些数据结构中,会用到一些排序,查找逻辑,这些形成了更高层次的高级数据结构。

常见的数据结构是栈和队列,用人话来说,就是排队,一个先进先出,一个先进后出。其次是树和图,树就是有一个树根节点,下面有很多子节点,类比自然界的树,图则可以类比自然界的地图。围绕这几种结构,有若干延伸,大家请看相关章节。

## 什么叫好的数据结构和好的算法

计算机资源是有限的,所以占用计算机资源越少的数据结构和算法越好。

人的生命是有限的,等待时间是有忍耐度的,所以能辅助程序越快完成工作的数据结构和算法越好。

所以出了个理论:时间和空间复杂度。

空间换时间,还是时间换空间。两者一般不能兼得,如果可以,那就是发明了一种更好的算法。在计算机科学发展的四五十年,这种发明还是比较少的。

期待有一天,量子计算机完善,然后极大解放生产力。

## 总结

程序设计=数据结构+算法

我们学习数据结构和算法,是为了更高效率写出更快,缺陷少的代码。

因为学习过,所以我们不需要从头再来,工作效率就提高了。

因为知道每种数据结构的复杂度和适用场景,我们自由组合改装,写出的代码,占用的计算机资源更少了,计算速度变快了,缺陷变少了。

我们要好好学习基本的数据结构和算法。
2 changes: 2 additions & 0 deletions basic/dregee.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 复杂度及渐进符号

2 changes: 2 additions & 0 deletions basic/master_method.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# 复杂度主方法

3 changes: 3 additions & 0 deletions basic/refer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 参考

- 算法[可视化](https://www.cs.usfca.edu/~galles/visualization/Algorithms.html)
Loading

0 comments on commit 2bcea86

Please sign in to comment.