Skip to content

Commit 5a8c8a8

Browse files
committed
Partial change some characters
1 parent 22ceb7a commit 5a8c8a8

File tree

17 files changed

+47
-47
lines changed

17 files changed

+47
-47
lines changed

docs/03_链表/linked_list.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class LinkedList(object):
3333
"""
3434
```
3535
實現我們會在影片中用画图來模擬並且手動原始碼實現,原始碼裡我們會標识每個步骤的時間複雜度。這裡請高度集中精力,
36-
雖然鏈表的思想很簡單,但是想要正確写對鏈表的操作原始碼可不容易,稍不留神就可能丢失一些步骤。
36+
雖然鏈表的思想很簡單,但是想要正確寫對鏈表的操作原始碼可不容易,稍不留神就可能丢失一些步骤。
3737
這裡我們還是會用簡單的單測來驗證原始碼是否按照預期工作。
3838

3939
來看下時間複雜度:
@@ -71,7 +71,7 @@ class Node(object):
7171
- 直接删除節點,當然如果给的是一個值,我們還是需要查找這個值在哪個節點? - 但是如果给了一個節點,我們把它拿掉,直接讓它的前後節點互相指過去不就行了?哇欧,删除就是 O(1) 了,兩步操作就行啦
7272

7373
好,废話不多說,我們在影片裡介绍怎麼實現一個双鏈表 ADT。你可以直接在本項目的 `docs/03_鏈表/double_link_list.py` 找到原始碼。
74-
最後讓我們看下它的時間複雜度:(這裡 CircularDoubleLinkedList 取大写字母缩写為 cdll)
74+
最後讓我們看下它的時間複雜度:(這裡 CircularDoubleLinkedList 取大寫字母缩寫為 cdll)
7575

7676
循環双端鏈表操作 | 平均時間複雜度 |
7777
---------------------------------------|----------------|

docs/03_链表/lru_cache.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ def fib(n):
1313

1414

1515
"""
16-
下邊就來写一個缓存装饰器來優化它。傳统方法是用個數組记录之前計算過的值,但是這種方式不够 Pythonic
16+
下邊就來寫一個缓存装饰器來優化它。傳统方法是用個數組记录之前計算過的值,但是這種方式不够 Pythonic
1717
"""
1818

1919

@@ -127,7 +127,7 @@ def test():
127127
print(time.time() - beg)
128128

129129

130-
# TODO 要怎麼给 lru 写單測
130+
# TODO 要怎麼给 lru 寫單測
131131

132132
if __name__ == '__main__':
133133
test()

docs/04_队列/queue.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ for i in range(100):
7979
- remove(node) # O(1)
8080

8181
啊哈,似乎删除頭尾都可以啦,而且都是 O(1) 的,完美。
82-
交给你一個艰巨的任务,實現双端陣列 Deque() ADT。你可以参考前幾章的任何原始碼,挑战一下這個任务,别忘记写單元測試呦。當然如果没想出來也没關系,後面我們實現堆疊的時候還會用到它,那裡我們會實現這個原始碼。
82+
交给你一個艰巨的任务,實現双端陣列 Deque() ADT。你可以参考前幾章的任何原始碼,挑战一下這個任务,别忘记寫單元測試呦。當然如果没想出來也没關系,後面我們實現堆疊的時候還會用到它,那裡我們會實現這個原始碼。
8383

8484

8585
# 思考题

docs/06_算法分析/big_o.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,4 @@ $n!$ | 階乘 | 旅行商問題 |
119119
如果你對數學感興趣,建議你閱讀《算法導論》『函數的增長』這一節 和《Data Structures and Algorithms in Python》第4章。
120120

121121

122-
(本章我用了 [MathJax](https://www.zybuluo.com/codeep/note/163962) 來书写一些簡單的數學公式,使用 "$"包含起來的就是數學公式)
122+
(本章我用了 [MathJax](https://www.zybuluo.com/codeep/note/163962) 來书寫一些簡單的數學公式,使用 "$"包含起來的就是數學公式)

docs/07_哈希表/hashtable.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ h(226) = 226 % M = 5
3333
h(903) = 903 % M = 6
3434
h(388) = 388 % M = 11
3535
```
36-
下邊我画個图演示整個插入過程(纯手工绘制,原谅我字写得不太優雅):
36+
下邊我画個图演示整個插入過程(纯手工绘制,原谅我字寫得不太優雅):
3737

3838
![](./insert_hash.png)
3939

@@ -54,7 +54,7 @@ h(388) = 388 % M = 11
5454
- 双重散列(double hashing): 重新計算 hash 結果。 $ h(k,i) = (h_1(k) + ih_2(k)) \% m $
5555

5656
我們選一個簡單的二次探查函數 $ h(k, i) = (home + i^2) \% m $,它的意思是如果
57-
遇到了衝突,我們就在原始計算的位置不断加上 i 的平方。我写了段原始碼來模擬整個計算下標的過程
57+
遇到了衝突,我們就在原始計算的位置不断加上 i 的平方。我寫了段原始碼來模擬整個計算下標的過程
5858

5959
```py
6060
inserted_index_set = set()
@@ -168,7 +168,7 @@ class HashTable(object):
168168
pass
169169
```
170170

171-
具體的實現和原始碼编写在影片裡講解。這個原始碼可不太好實現,稍不留神就會有错,我們還是通過编写單元測試驗證原始碼的正確性
171+
具體的實現和原始碼编寫在影片裡講解。這個原始碼可不太好實現,稍不留神就會有错,我們還是通過编寫單元測試驗證原始碼的正確性
172172

173173
# 思考题
174174
- 請你分析下哈希表插入和删除元素的平均時間複雜度是多少?我們都實現原始碼了,相信這個問題你可以回答上來

docs/08_字典/dict.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# 字典 dict
22

33
上一章我們介绍了哈希表,其實 python 内置的 dict 就是用哈希表實現的,所以這一章實現 dict 就非常簡單了。
4-
當然 cpython 使用的是 c 语言實現的,远比我們写的复杂得多 (cpython/Objects/dictobject.c)。
5-
上一章我們用 python 自己写的一個 Array 來代表定長數組,然後用它實現的 HashTable,它支持三個最基本的方法
4+
當然 cpython 使用的是 c 语言實現的,远比我們寫的复杂得多 (cpython/Objects/dictobject.c)。
5+
上一章我們用 python 自己寫的一個 Array 來代表定長數組,然後用它實現的 HashTable,它支持三個最基本的方法
66

77
- add(key ,value): 有 key 则更新,否则插入
88
- get(key, default=None): 或者 key 的值,不存在返回默认值 None
@@ -23,7 +23,7 @@ class DictADT(HashTable):
2323
pass
2424
```
2525

26-
影片裡我們將演示如何實現這些方法,並且写單測驗證正確性
26+
影片裡我們將演示如何實現這些方法,並且寫單測驗證正確性
2727

2828
# Hashable
2929
作為 dict 的 key 必须是可哈希的,也就是說不能是 list 等可变對象。不信你在 ipython 裡運行如下原始碼:

docs/10_递归/recursion.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
![](./fact.png)
1818

19-
我們很容易根據它的定義写出這樣一個遞迴函數,因為它本身就是遞迴定義的。
19+
我們很容易根據它的定義寫出這樣一個遞迴函數,因為它本身就是遞迴定義的。
2020

2121
```py
2222
def fact(n):
@@ -25,7 +25,7 @@ def fact(n):
2525
else:
2626
return n * fact(n-1)
2727
```
28-
看吧,幾乎完全是按照定義來写的。我們來看下遞迴函數的幾個特點:
28+
看吧,幾乎完全是按照定義來寫的。我們來看下遞迴函數的幾個特點:
2929

3030
- 遞迴必须包含一個基本的出口(base case),否则就會無限遞迴,最终导致堆疊溢出。比如這裡就是 n == 0 返回 1
3131
- 遞迴必须包含一個可以分解的問題(recursive case)。 要想求得 fact(n),就需要用 n * fact(n-1)
@@ -34,7 +34,7 @@ def fact(n):
3434

3535
# 調用堆疊
3636
看了上一個例子你可能覺得遞迴好簡單,先别着急,我們再舉個簡單的例子,上邊我們並没有講遞迴如何工作的。
37-
假如讓你輸出從 1 到 10 這十個數字,如果你是個正常人的話,我想你的第一反应都是這麼写
37+
假如讓你輸出從 1 到 10 這十個數字,如果你是個正常人的話,我想你的第一反应都是這麼寫
3838

3939
```py
4040
def print_num(n):
@@ -46,7 +46,7 @@ if __name__ == '__main__':
4646
print_num(10)
4747
```
4848

49-
我們嘗試写一個遞迴版本,不就是自己調用自己嘛:
49+
我們嘗試寫一個遞迴版本,不就是自己調用自己嘛:
5050

5151
```py
5252
def print_num_recursive(n):

docs/11_线性查找与二分查找/search.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ assert linear_search_recusive(number_list, 8) == -1
5151
assert linear_search_recusive(number_list, 7) == 7
5252
assert linear_search_recusive(number_list, 0) == 0
5353
```
54-
這裡的 assert 我多写了幾個,包括正常情况、异常情况和邊界值等,因為遞迴比较容易出错。注意這裡的兩個遞迴出口。
54+
這裡的 assert 我多寫了幾個,包括正常情况、异常情况和邊界值等,因為遞迴比较容易出错。注意這裡的兩個遞迴出口。
5555
當然業務原始碼裡如果碰到這種問題我們肯定是選上邊最直白的方式來實現,要不你的同事肯定想打你。
5656

5757
# 二分查找
@@ -61,7 +61,7 @@ assert linear_search_recusive(number_list, 0) == 0
6161
- 一尺之棰,日取其半,万世不竭
6262
- 有些民間股神,告诉一堆人某個股票會涨,告诉另一半人會跌。後來真涨了,慢慢又告诉信了他的一半人另一個股票會涨,另一半說會跌。就這樣韭菜多了总有一些人信奉他為股神。。。
6363

64-
其實之前写過博客[《抱歉,我是開發,你居然讓我写單測[影片]](https://zhuanlan.zhihu.com/p/35352024)講過二分查找,當時主要是為了引入單元測試這個概念的,因為很多不正规的項目原始碼很糙,更别說写單測了。這裡我就直接贴原始碼啦
64+
其實之前寫過博客[《抱歉,我是開發,你居然讓我寫單測[影片]](https://zhuanlan.zhihu.com/p/35352024)講過二分查找,當時主要是為了引入單元測試這個概念的,因為很多不正规的項目原始碼很糙,更别說寫單測了。這裡我就直接贴原始碼啦
6565

6666
```py
6767
def binary_search(sorted_array, val):
@@ -98,13 +98,13 @@ def test_binary_search():
9898

9999

100100
# 思考题
101-
- 给你個挑战,用遞迴來實現本章的二分查找。你要十分注意邊界條件,注意用單測測試呦,在你写原始碼的時候,可能會碰到邊界問題或者無穷遞迴等。 如果你想不起來,可以看看本章的原始碼示例
101+
- 给你個挑战,用遞迴來實現本章的二分查找。你要十分注意邊界條件,注意用單測測試呦,在你寫原始碼的時候,可能會碰到邊界問題或者無穷遞迴等。 如果你想不起來,可以看看本章的原始碼示例
102102
- 二分查找有一個变形,比如我們想在一個有序數組中插入一個值之後,數組仍保持有序,請你找出這個位置。(bisect 模塊)
103103

104104

105105
# 延伸閱讀
106106
這裡没给鏈接,請善用 google 等搜索引擎和 Dash(mac) 等文档查询工具,在你學習原始碼的過程中你會非常頻繁地使用它們。
107-
或者如果你有時間也可以跳轉到這些模塊的源碼,看看它們的實現方式。標准库都是些高手写的,肯定能學到一些姿势。
107+
或者如果你有時間也可以跳轉到這些模塊的源碼,看看它們的實現方式。標准库都是些高手寫的,肯定能學到一些姿势。
108108

109109
- 閱讀 python 文档關於二分的 bisect 模塊。
110110
- 閱讀 python 文档 itertools 相關模塊和常見的幾個函數 takewhile, dropwhile, from_iterable, count, tee 等用法

docs/13_高级排序算法/quick_sort.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
![](./quick_sort.png)
1616

17-
根據這個想法我們可以快速写出快排的原始碼,簡直就是在翻译上邊的描述:
17+
根據這個想法我們可以快速寫出快排的原始碼,簡直就是在翻译上邊的描述:
1818

1919
```py
2020
def quicksort(array):
@@ -33,7 +33,7 @@ def test_quicksort():
3333
random.shuffle(seq)
3434
assert quicksort(seq) == sorted(seq)
3535
```
36-
是不是很簡單,下次面試官讓你手写快排你再写不出來就有點不太合适啦。 當然這個實現有兩個不好的地方:
36+
是不是很簡單,下次面試官讓你手寫快排你再寫不出來就有點不太合适啦。 當然這個實現有兩個不好的地方:
3737

3838
- 第一是它需要额外的存儲空間,我們想實現 inplace 原地排序。
3939
- 第二是它的 partition 操作每次都要兩次遍历整個數組,我們想改善一下。
@@ -102,7 +102,7 @@ T(n) = 2T(n/2) + n
102102
- 最坏的情况下快排的時間複雜度是多少?什麼時候會發生這種情况?
103103
- 我們實現的快排是稳定的啵?
104104
- 選择基准值如果選不好就可能导致複雜度升高,算导中提到了一種『median of 3』策略,就是說選择 pivot 的時候 從子數組中随機選三個元素,再取它的中位數,你能實現這個想法嗎?這裡我們的原始碼很簡單地取了第一個元素作為 pivot
105-
- 利用快排中的 partition 操作,我們還能實現另一個算法,nth_element,快速查找一個無序數組中的第 n 大元素,請你嘗試實現它並编写單測。其實這個函數是 C++ STL 中的一個函數。
105+
- 利用快排中的 partition 操作,我們還能實現另一個算法,nth_element,快速查找一個無序數組中的第 n 大元素,請你嘗試實現它並编寫單測。其實這個函數是 C++ STL 中的一個函數。
106106
- 你知道 Python 内置的 sorted 如何實現的嗎?請你 Google 相關資料了解下。很多内置的排序都使用了快排的改良版。
107107

108108

docs/14_树与二叉树/tree.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
- 树的宽度(width): 二叉树的宽度指的是包含最多節點的层级的節點數
3636
- 树的 size:二叉树的節點总個數。
3737

38-
一棵 size 為 n 的二叉树高度最多可以是 n,最小的高度是 $ \lfloor lgn \rfloor + 1 $,這裡 log 以 2 為底簡写為
38+
一棵 size 為 n 的二叉树高度最多可以是 n,最小的高度是 $ \lfloor lgn \rfloor + 1 $,這裡 log 以 2 為底簡寫為
3939
lgn,和算法導論保持一致。這個結果你只需要用高中的累加公式就可以得到。
4040

4141
# 一些特殊的二叉树
@@ -77,7 +77,7 @@ class BinTree(object):
7777
self.root = root
7878
```
7979

80-
怎麼构造上图中的二叉树呢,似乎其他課本没找到啥例子(有些例子是写了一堆嵌套節點來定義,很难搞清楚层次關系),我自己定義了一種方法,首先我們輸入節點信息,仔细看下邊原始碼,叶子節點的 left 和 right 都是 None,並且只有一個根節點 A:
80+
怎麼构造上图中的二叉树呢,似乎其他課本没找到啥例子(有些例子是寫了一堆嵌套節點來定義,很难搞清楚层次關系),我自己定義了一種方法,首先我們輸入節點信息,仔细看下邊原始碼,叶子節點的 left 和 right 都是 None,並且只有一個根節點 A:
8181

8282
```py
8383
node_list = [
@@ -248,7 +248,7 @@ class Queue(object): # 借助内置的 deque 我們可以迅速實現一個 Que
248248

249249

250250
# 反轉二叉树
251-
之所以單拎出來說這個是因為 mac 下著名的 brew 工具作者据說是因為面試 google 白板编程没写出來反轉二叉树跪了。然後人家就去了苹果 😂。其實吧和遍历操作相比也没啥太大區别,遞迴交換就是了:
251+
之所以單拎出來說這個是因為 mac 下著名的 brew 工具作者据說是因為面試 google 白板编程没寫出來反轉二叉树跪了。然後人家就去了苹果 😂。其實吧和遍历操作相比也没啥太大區别,遞迴交換就是了:
252252

253253
```py
254254
def reverse(self, subtree):

docs/15_堆与堆排序/heap_and_heapsort.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ right = 2 * i + 2
3838
超出下標表示没有對应的孩子節點。
3939

4040
# 實現一個最大堆
41-
我們將在影片裡详细描述和编写各個操作
41+
我們將在影片裡详细描述和编寫各個操作
4242

4343
```py
4444
class MaxHeap(object):
@@ -80,7 +80,7 @@ class MaxHeap(object):
8080
largest = ndx
8181
if (left < self._count and # 有左孩子
8282
self._elements[left] >= self._elements[largest] and
83-
self._elements[left] >= self._elements[right]): # 原书這個地方没写實際上找的未必是largest
83+
self._elements[left] >= self._elements[right]): # 原书這個地方没寫實際上找的未必是largest
8484
largest = left
8585
elif right < self._count and self._elements[right] >= self._elements[largest]:
8686
largest = right
@@ -100,7 +100,7 @@ def test_maxheap():
100100
```
101101

102102
# 實現堆排序
103-
上邊我們實現了最大堆,每次我們都能 extract 一個最大的元素了,於是一個倒序排序函數就能很容易写出來了
103+
上邊我們實現了最大堆,每次我們都能 extract 一個最大的元素了,於是一個倒序排序函數就能很容易寫出來了
104104

105105
```py
106106
def heapsort_reverse(array):
@@ -123,7 +123,7 @@ def test_heapsort_reverse():
123123

124124
# Python 裡的 heapq 模塊
125125
python 其實自带了 heapq 模塊,用來實現堆的相關操作,原理是類似的。請你閱讀相關文档並使用内置的 heapq 模塊完成堆排序。
126-
一般我們刷题或者写業務原始碼的時候,使用這個内置的 heapq 模塊就够用了,内置的實現了是最小堆。
126+
一般我們刷题或者寫業務原始碼的時候,使用這個内置的 heapq 模塊就够用了,内置的實現了是最小堆。
127127

128128

129129
# Top K 問題
@@ -141,7 +141,7 @@ python 其實自带了 heapq 模塊,用來實現堆的相關操作,原理是
141141
慢慢就被替換成了最大的那些值,並且最後堆顶是最大的 topk 個值中的最小值。
142142
(比如1000個數找10個,最後堆裡剩餘的是 [990, 991, 992, 996, 994, 993, 997, 998, 999, 995],第一個 990 最小)
143143

144-
按照這個思路很容易写出來原始碼
144+
按照這個思路很容易寫出來原始碼
145145

146146
```py
147147
import heapq

docs/15_堆与堆排序/heap_and_heapsort.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def _siftdown(self, ndx):
8888
largest = ndx
8989
if (left < self._count and # 有左孩子
9090
self._elements[left] >= self._elements[largest] and
91-
self._elements[left] >= self._elements[right]): # 原书這個地方没写實際上找的未必是largest
91+
self._elements[left] >= self._elements[right]): # 原书這個地方没寫實際上找的未必是largest
9292
largest = left
9393
elif right < self._count and self._elements[right] >= self._elements[largest]:
9494
largest = right

docs/16_优先级队列/priority_queue.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# 實現優先级陣列
77
優先级陣列(Priority Queue) 顧名思義,就是入隊的時候可以给一個優先级,通常是個數字或者時間戳等,
8-
當出隊的時候我們希望按照给定的優先级出隊,我們按照 TDD(測試驱動開發) 的方式先來写測試原始碼
8+
當出隊的時候我們希望按照给定的優先级出隊,我們按照 TDD(測試驱動開發) 的方式先來寫測試原始碼
99

1010
```py
1111
def test_priority_queue():
@@ -22,7 +22,7 @@ def test_priority_queue():
2222
assert res == ['purple', 'orange', 'black', 'white']
2323
```
2424

25-
上邊就是期望的行為,写完測試原始碼後我們來编写優先级陣列的原始碼,按照出隊的時候最大優先级先出的顺序:
25+
上邊就是期望的行為,寫完測試原始碼後我們來编寫優先级陣列的原始碼,按照出隊的時候最大優先级先出的顺序:
2626

2727

2828
```py

docs/16_优先级队列/priority_queue.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def _siftdown(self, ndx):
8888
largest = ndx
8989
if (left < self._count and # 有左孩子
9090
self._elements[left] >= self._elements[largest] and
91-
self._elements[left] >= self._elements[right]): # 原书這個地方没写實際上找的未必是largest
91+
self._elements[left] >= self._elements[right]): # 原书這個地方没寫實際上找的未必是largest
9292
largest = left
9393
elif right < self._count and self._elements[right] >= self._elements[largest]:
9494
largest = right

docs/17_二叉查找树/binary_search_tree.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ bst = BST.build_from(NODE_LIST)
193193

194194
![](./find_successor.png)
195195

196-
我們開始编写原始碼實現,和之前的操作類似,我們還是通過辅助函數的形式來實現,這個遞迴函數會比较复杂,請你仔细理解:
196+
我們開始编寫原始碼實現,和之前的操作類似,我們還是通過辅助函數的形式來實現,這個遞迴函數會比较复杂,請你仔细理解:
197197

198198
```py
199199
def _bst_remove(self, subtree, key):

docs/18_图与图的遍历/graph.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ dfs(GRAPH, 'A') # A B C I D G F E H
134134

135135

136136
# 思考题
137-
- DFS 中我們使用到了遞迴,請你用堆疊來改写這個函數?(原始碼裡有答案,我建議你先嘗試自己實現)
137+
- DFS 中我們使用到了遞迴,請你用堆疊來改寫這個函數?(原始碼裡有答案,我建議你先嘗試自己實現)
138138

139139
# 延伸閱讀
140140
图的算法還有很多,這裡就不一一列舉了,感興趣的讀者可以繼续閱讀一下材料。

0 commit comments

Comments
 (0)