├── .gitignore ├── 02.array └── 02.Array.py ├── 03.linked_list ├── JosephRing_LinkedList.py ├── JosephRing_array.py ├── LRUCache_array.py ├── LRUCache_linkedlist.py └── palind_rome_linkedlist.py ├── 04.stack ├── array_stack.py ├── linked_stack.py ├── list_stack.py └── simple_browser.py ├── 05.queue ├── array_queue.py ├── blocking_queue.py ├── circular_queue.py ├── dynamic_array_queue.py └── linked_queue.py ├── 06.recursion ├── combination_str.py ├── fibonacci_sequence.py ├── find_root_referrer_id.py ├── perm_com_str.py ├── permutation_str.py └── tree_dir.py ├── 07.sorts ├── bubble_sort.py ├── bucket_sort.py ├── counting_sort.py ├── insertion_sort.py ├── kth_smallest.py ├── logfile_merge.py ├── merge_sort.py ├── quick_sort.py ├── quick_user_sort_by_age.py ├── radix_sort.py ├── selection_sort.py ├── shell_sort.py └── string_sort.py ├── 09.binary_search ├── binary_search.py ├── binary_search_circle_array.py ├── bsearch_sqrt.py ├── ip.py └── ip.txt ├── 10.skip_list └── SkipList.py ├── 11.hash_table ├── HashTable.py ├── LRUCacheHashTable.py ├── SortedSet.py ├── access.log ├── common_string.py ├── hash_code.py └── url_count_sort.py ├── 13.binary_tree ├── binary_search_tree.py └── binary_tree.py ├── 14.red_black_tree └── red_black_tree.py ├── 15.recursion_tree ├── cell_division.py └── permutation_str.py ├── 16.heap ├── Heap.py ├── TopK.py ├── __pycache__ │ └── Heap.cpython-37.pyc ├── heap_sort.py ├── median_num.py └── merge_small_file.py ├── 19.string_match ├── bf_rk.py ├── bm.py └── kmp.py ├── 20.trie ├── trie_adv.py └── trie_base.py ├── 21.ac_automata ├── ac_automata.py └── ac_automata_adv.py ├── 23.divide ├── merge_sort_counting.py └── min_distance_point.py ├── 24.back_track ├── 01_bag.py ├── 01_bag_adv.py ├── eight_queens.py ├── permutations.py └── regex.py ├── 25.dynamic_programming ├── 01_bag.py ├── __pycache__ │ └── min_dist.cpython-37.pyc ├── coins_problem.py ├── double11advance.py ├── lengthOfLIS.py ├── max_envelopes.py ├── min_dist.py ├── min_edit_dist.py └── yh_triangle.py ├── 26.topological_sorting └── topological_sorting.py ├── 27.weighted_graph ├── A-star.py └── dijkstra.py ├── 28.bitmap └── bitmap.py ├── README.md ├── docs ├── .nojekyll ├── 01.入门篇.md ├── 02.数组.md ├── 03.链表.md ├── 04.栈.md ├── 05.队列.md ├── 06.递归.md ├── 07.排序.md ├── 09.二分查找.md ├── 10.跳表.md ├── 11.散列表.md ├── 12.哈希算法.md ├── 13.二叉树基础.md ├── 14.红黑树.md ├── 15.递归树.md ├── 16.堆.md ├── 17.图的表示.md ├── 18.深度和广度优先搜索.md ├── 19.字符串匹配基础.md ├── 20.Trie树.md ├── 21.AC自动机.md ├── 22.贪心算法.md ├── 23.分治算法.md ├── 24.回溯算法.md ├── 25.动态规划.md ├── 26.拓扑排序.md ├── 27.有权图的应用:最短路径.md ├── 28.位图&布隆过滤器.md ├── 29.B+树.md ├── 30.索引.md ├── 31.并行算法.md ├── 32.Redis用到的数据结构.md ├── 33.搜索引擎的理论基础.md ├── 34.高性能队列Disruptor.md ├── 35.微服务的鉴权限流接口.md ├── 36.短网址服务系统.md ├── 37.权衡选择数据结构和算法.md ├── 38.leetcode练习题.md ├── README.md ├── _coverpage.md ├── _sidebar.md ├── favicon.ico ├── imgs │ ├── 2 │ │ ├── 1.jpg │ │ ├── 1570432607992.png │ │ ├── 1570432750746.png │ │ ├── 1570432783901.png │ │ ├── 1570432823131.png │ │ ├── 1570433001763.png │ │ ├── 1570433061344.png │ │ ├── 1570433080092.png │ │ ├── 1570433106298.png │ │ ├── 1570433133761.png │ │ ├── 1570433152459.png │ │ ├── 1570433167414.png │ │ ├── 1570433190306.png │ │ ├── 1570433217183.png │ │ ├── 1570433339703.png │ │ ├── 1570433366474.png │ │ ├── 1570433383574.png │ │ ├── 1570433406655.png │ │ ├── 1570433422411.png │ │ ├── 1570433438772.png │ │ ├── 1570433457896.png │ │ ├── 1570433479539.png │ │ ├── 1570433507770.png │ │ ├── 1570433522754.png │ │ ├── 1570433907877.png │ │ ├── 1570434107982.png │ │ ├── 1570434132748.png │ │ ├── 1570434178012.png │ │ ├── 1570434192005.png │ │ ├── 1570434207006.png │ │ ├── 1570434239490.png │ │ ├── 1570434286245.png │ │ ├── 1570434301993.png │ │ ├── 1570434319108.png │ │ ├── 1570434336773.png │ │ ├── 1570434356028.png │ │ ├── 1570434375850.png │ │ ├── 1570434553802.png │ │ ├── 1570434823959.png │ │ ├── 1570439501672.png │ │ ├── 1570439557784.png │ │ ├── 1570439590377.png │ │ ├── 1570439607551.png │ │ ├── 1570439636166.png │ │ ├── 1570439866145.png │ │ ├── 1570439893869.png │ │ ├── 1570439941723.png │ │ ├── 1570440486953.png │ │ ├── 1570440501975.png │ │ ├── 1570441637365.png │ │ ├── 1570441654764.png │ │ ├── 1570442602270.png │ │ ├── 1570442615779.png │ │ ├── 1570442649156.png │ │ ├── 1570442675055.png │ │ ├── 1570442695929.png │ │ ├── 1570442729225.png │ │ ├── 1570442776661.png │ │ ├── 1570442793990.png │ │ ├── 1570442809447.png │ │ ├── 1570442938362.png │ │ ├── 1570442960343.png │ │ ├── 1570442976703.png │ │ ├── 1570442999808.png │ │ ├── 1570443033230.png │ │ ├── 1570443204350.png │ │ ├── 1570443225487.png │ │ ├── 1570443243282.png │ │ ├── 1570443319623.png │ │ ├── 1570443360066.png │ │ ├── 1570443376432.png │ │ ├── 1570443391552.png │ │ ├── 1570443537331.png │ │ ├── 1570443554236.png │ │ ├── 1570443690705.png │ │ ├── 1570444279777.png │ │ ├── 1570444335291.png │ │ ├── 1570444363236.png │ │ ├── 1570444377068.png │ │ ├── 1570444390843.png │ │ ├── 1570444403668.png │ │ ├── 1570444415962.png │ │ ├── 1570444429469.png │ │ ├── 1570444448382.png │ │ ├── 1570444524770.png │ │ ├── 1570444541558.png │ │ ├── 1570444560417.png │ │ ├── 1570444574980.png │ │ ├── 1570444644303.png │ │ ├── 1570444657714.png │ │ ├── 1570444672716.png │ │ ├── 1570444686811.png │ │ ├── 1570444901543.png │ │ ├── 1570444918651.png │ │ ├── 1570444949922.png │ │ ├── 1570444992882.png │ │ ├── 1570445009767.png │ │ ├── 1570445028474.png │ │ ├── 1570445049617.png │ │ ├── 1570445070428.png │ │ ├── 1570445087285.png │ │ ├── 1570445105711.png │ │ ├── 1570445145477.png │ │ ├── 1570445163520.png │ │ ├── 1570445186041.png │ │ ├── 1570445206401.png │ │ ├── 1570445220062.png │ │ ├── 1570445234190.png │ │ ├── 1570445246373.png │ │ ├── 1570445651316.png │ │ ├── 1570445665505.png │ │ ├── 1570446242483.png │ │ ├── 1570446604211.png │ │ ├── 1570448039211.png │ │ ├── 1570448501976.png │ │ ├── 1570493298643.png │ │ ├── 1570493443825.png │ │ ├── 1570493581004.png │ │ ├── 1570493595417.png │ │ ├── 1570493622909.png │ │ ├── 1570493638378.png │ │ ├── 1570493827984.png │ │ ├── 1570494076865.png │ │ ├── 1570494236321.png │ │ ├── 1570494449408.png │ │ ├── 1570494627902.png │ │ ├── 1570494651114.png │ │ ├── 1570496431493.png │ │ ├── 1570496493417.png │ │ ├── 1570496545408.png │ │ ├── 1570496832646.png │ │ ├── 1570497121476.png │ │ ├── 1570497151653.png │ │ ├── 1570497174693.png │ │ ├── 1570497255139.png │ │ ├── 1570497334285.png │ │ ├── 1570497356895.png │ │ ├── 1570497374244.png │ │ ├── 1570497713857.png │ │ ├── 1570497928999.png │ │ ├── 1570497975150.png │ │ ├── 1570498286430.png │ │ ├── 1570498355108.png │ │ ├── 1570498417310.png │ │ ├── 1570498447098.png │ │ ├── 1570498470428.png │ │ ├── 1570498502925.png │ │ ├── 1570498760377.png │ │ ├── 1570498774667.png │ │ ├── 1570498799523.png │ │ ├── 1570498845772.png │ │ ├── 1570498875778.png │ │ ├── 1570498905387.png │ │ ├── 1570498935264.png │ │ ├── 1570498956983.png │ │ ├── 1570498975996.png │ │ ├── 1570498996673.png │ │ ├── 1570499030429.png │ │ ├── 1570499071780.png │ │ ├── 1570499164110.png │ │ ├── 1570499179335.png │ │ ├── 1570499211481.png │ │ ├── 1570499239474.png │ │ ├── 1570499252464.png │ │ ├── 1570499479897.png │ │ ├── 1570499526476.png │ │ ├── 1570499540559.png │ │ ├── 1570500434769.png │ │ ├── 1570500456458.png │ │ ├── 1570500470544.png │ │ ├── 1570500495719.png │ │ ├── 1570500591632.png │ │ ├── 1570500612306.png │ │ ├── 1570500742068.png │ │ ├── 1570500755759.png │ │ ├── 1570500769943.png │ │ ├── 1570500782819.png │ │ ├── 1570500806433.png │ │ ├── 1570500850207.png │ │ ├── 1570501134514.png │ │ ├── 1570501292623.png │ │ ├── 1570501375909.png │ │ ├── 1570501407500.png │ │ ├── 1570501425196.png │ │ ├── 1570503357732.png │ │ ├── 1570503806038.png │ │ ├── 1570503949180.png │ │ ├── 1570504039881.png │ │ ├── 1570504227618.png │ │ ├── 1570504409871.png │ │ ├── 1570504508147.png │ │ ├── 1570504524638.png │ │ ├── 1570504543161.png │ │ ├── 1570504610402.png │ │ ├── 1570504635185.png │ │ ├── 1570504645294.png │ │ ├── 1570504739176.png │ │ ├── 1570504780404.png │ │ ├── 1570504802113.png │ │ ├── 1570504823431.png │ │ ├── 1570505483818.png │ │ ├── 1570505502413.png │ │ ├── 1570505701692.png │ │ ├── 1570505728487.png │ │ ├── 1570505743187.png │ │ ├── 1570505830434.png │ │ ├── 1570506063479.png │ │ ├── 1570506081739.png │ │ ├── 1570506827342.png │ │ ├── 1570506847019.png │ │ ├── 1570506862261.png │ │ ├── 1570506881996.png │ │ ├── 1570506917393.png │ │ ├── 1570506939090.png │ │ ├── 1570506958575.png │ │ ├── 1570507062242.png │ │ ├── 1570507106426.png │ │ ├── 1570507123681.png │ │ ├── 1573896556022.png │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ └── 7.jpg │ ├── 3 │ │ ├── 1570510971957.png │ │ ├── 1570510987625.png │ │ ├── 1570511130593.png │ │ ├── 1570511195844.png │ │ ├── 1570511212559.png │ │ ├── 1570511230082.png │ │ ├── 1570511244884.png │ │ ├── 1570511356767.png │ │ ├── 1570511408536.png │ │ ├── 1570511514354.png │ │ ├── 1570511532621.png │ │ ├── 1570511548680.png │ │ ├── 1570511567694.png │ │ ├── 1570511582543.png │ │ ├── 1570511599857.png │ │ ├── 1570511618259.png │ │ ├── 1570511638896.png │ │ ├── 1570511733024.png │ │ ├── 1570511752337.png │ │ ├── 1570511775562.png │ │ └── 1570511790220.png │ ├── 1.jpg │ ├── 1475054023258693.jpg │ ├── 1570439941723.png │ ├── 1570507062242.png │ ├── 1570507106426.png │ ├── 1570507123681.png │ ├── 1570684986266.png │ ├── 1570723469548.png │ ├── 1570723505115.png │ ├── 1571040886966.png │ ├── 1571226184051.png │ ├── 1571227085370.png │ ├── 1571762267701.png │ ├── 1572778109574.png │ ├── 1572782164334.png │ ├── 1572834037956.png │ ├── 1572834957032.png │ ├── 1573352954856.png │ ├── 1573896556022.png │ ├── 1574073361716.jpg │ ├── 1574085510892.png │ ├── 4.jpg │ ├── 496275-20180527123823742-514849225.png │ ├── 496275-20180527124958975-24745120.png │ ├── 498077-20160822172408386-366341651.png │ ├── 498077-20160822172431933-546286787.png │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 7GJ3DU}2$U2D@T[[C84$[]U.png │ ├── 8.jpg │ ├── 8926909-e188847813d04828.webp │ ├── Huffman_algorithm.gif │ ├── TABLE8.JPG │ ├── arr.gif │ ├── booklist.jpg │ ├── d9yCzX5UJ6eT.png │ ├── jvm1.jpg │ ├── jvm2.jpg │ ├── jvm3.jpg │ ├── jvm4.jpg │ ├── oOAlvULKOjzy.png │ ├── v2-a576dfe6a192cca2a055ceb59a49ac27_hd.jpg │ └── v2-d1ff6d696834fa2d02bcae74b5cbc0af_hd.jpg ├── index.html └── sw.js └── logs ├── 0.log ├── 1.log ├── 2.log ├── 3.log ├── 4.log ├── 5.log ├── 6.log ├── 7.log ├── 8.log └── 9.log /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/* 2 | /java/* 3 | /python/* 4 | /11.hash_table/log_clean.py 5 | /14.red_black_tree/Red_Black_Tree.png 6 | /13.binary_tree/binary_search_tree.png 7 | /07.sorts/out.log 8 | /16.heap/out.log 9 | -------------------------------------------------------------------------------- /02.array/02.Array.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiao-xiaoming' 3 | 4 | 5 | class Array: 6 | """一个包装list的简单数组,支持插入、删除、按照下标随机访问操作 7 | 数组中的数据是任意类型的 8 | """ 9 | 10 | def __init__(self, capacity: int = 10): 11 | """初始化方法,capacity表示数组容量""" 12 | self._data = [] 13 | self._capacity = capacity 14 | 15 | def __len__(self) -> int: 16 | return len(self._data) 17 | 18 | def __iter__(self): 19 | for item in self._data: 20 | yield item 21 | 22 | def __repr__(self): 23 | return str(self._data) 24 | 25 | def find(self, index: int) -> object: 26 | '''根据索引,找到数据中的元素并返回 27 | 参数: 28 | index:将要查找的数据的下标 29 | 返回: 30 | 如果查找成功,则返回找到的数据 31 | 如果角标越界,则返回False 32 | ''' 33 | if (index < 0 or index >= len(self)): 34 | return -1 35 | return self._data[index] 36 | 37 | def delete(self, index: int) -> bool: 38 | '''根据索引,删除数组中元素. 39 | 参数: 40 | index:将要删除的数据的下标 41 | 返回: 42 | 如果删除成功,则返回True 43 | 如果删除失败,则返回False 44 | ''' 45 | if (index < 0 or index >= len(self)): 46 | return False 47 | self._data.pop(index) 48 | return True 49 | 50 | def insert(self, index: int, value: int) -> bool: 51 | '''数组插入数据操作. 52 | 参数: 53 | index:将要插入的下标 54 | value:将要插入的数据 55 | 返回: 56 | 如果插入成功,则返回True 57 | 如果插入失败,则返回False 58 | ''' 59 | if index < 0 or len(self) >= self._capacity: 60 | return False 61 | else: 62 | self._data.insert(index, value) 63 | return True 64 | 65 | 66 | if __name__ == "__main__": 67 | array = Array(5) 68 | array.insert(0, 3) 69 | array.insert(0, 4) 70 | array.insert(1, 5) 71 | array.insert(3, 9) 72 | array.insert(3, 10) 73 | assert array.insert(0, 100) is False 74 | print(array) 75 | assert len(array) == 5 76 | assert array.find(1) == 5 77 | assert array.delete(4) is True 78 | print(array) 79 | array.insert(3, 7) 80 | print(array) 81 | 82 | -------------------------------------------------------------------------------- /03.linked_list/JosephRing_LinkedList.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到m报数), 6 | 凡报到m的人退出圈子,直到船上仅剩 r人为止,问都有哪些编号的人下船了呢?。 7 | 假设n=30,m=9,r=15 8 | """ 9 | 10 | 11 | class ListNode(object): 12 | def __init__(self, val, next_node=None): 13 | self.val = val 14 | self.next = next_node 15 | 16 | 17 | n, m, r = 30, 9, 15 18 | # 开始构建环 19 | head = ListNode(1) 20 | p = head 21 | for i in range(2, n + 1): 22 | p.next = ListNode(i) 23 | p = p.next 24 | p.next = head 25 | # 构建完成,开始报数 26 | 27 | result = [] # 用于保存出列顺序 28 | p = head 29 | count = 1 # 第一个人报的数为1 30 | while n != r: 31 | prev: ListNode = p 32 | p = p.next 33 | count += 1 34 | # 凡报到m的人退出圈子 35 | if count == m: 36 | result.append(p.val) 37 | prev.next = prev.next.next 38 | count = 0 39 | n -= 1 40 | print("报到%d的人的出列顺序:" % m, result) 41 | -------------------------------------------------------------------------------- /03.linked_list/JosephRing_array.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | """ 4 | 题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到m报数), 5 | 凡报到m的人退出圈子,直到船上仅剩 r人为止,问都有哪些编号的人下船了呢?。 6 | 假设n=30,m=9,r=15 7 | """ 8 | 9 | n, m, r = 30, 9, 15 10 | circle = list(range(1, n + 1)) 11 | # index+1代表当前报数的人在剩余报数人群中的编号 12 | index = 0 13 | result = [] 14 | while len(circle) > r: 15 | index += m - 1 16 | if (index >= len(circle)): 17 | index -= len(circle) 18 | result.append(circle.pop(index)) 19 | print("报到%d的人的出列顺序:" % m, result) 20 | -------------------------------------------------------------------------------- /03.linked_list/LRUCache_array.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiao-xiaoming' 3 | 4 | import random 5 | 6 | 7 | class LRUCache: 8 | ''' 9 | 通过数组array实现的简易 LRU缓存 10 | 维护一个list,越靠近尾部表示是越早之前访问的。 11 | ''' 12 | def __init__(self, capacity: int = 10): 13 | self.cap = capacity 14 | self._data = [] # 存储数据 15 | 16 | def __len__(self): 17 | return len(self._data) 18 | 19 | def __repr__(self): 20 | return str(self._data) 21 | 22 | def get(self, val: object) -> bool: 23 | """ 24 | 获取指定缓存数据 25 | 参数: 26 | val:要获取的数据 27 | 返回: 28 | 存在于缓存中,返回True,否则返回 False。 29 | """ 30 | for i in range(len(self._data)): 31 | if self._data[i] == val: 32 | self._data.insert(0, self._data.pop(i)) 33 | return True 34 | 35 | # 如果此数据没有缓存在链表中 36 | self._data.insert(0, val) 37 | # 添加数据导致超过容量则要删除尾节点 38 | if len(self) > self.cap: 39 | self._data.pop(len(self)-1) 40 | return False 41 | 42 | 43 | if __name__ == '__main__': 44 | cache = LRUCache(5) 45 | for n in range(40): 46 | i = random.randint(0, 7) 47 | print("cache.get(%d)" % i, cache.get(i), cache) 48 | -------------------------------------------------------------------------------- /03.linked_list/LRUCache_linkedlist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiao-xiaoming' 3 | 4 | import random 5 | 6 | 7 | class ListNode(object): 8 | def __init__(self, val, next=None): 9 | self.val = val 10 | self.next = next 11 | 12 | 13 | class LRUCache: 14 | """ 15 | 一个 LRU 缓存 16 | 维护了一个有序单链表,越靠近链表尾部的结点是越早之前访问的。 17 | """ 18 | 19 | def __init__(self, capacity: int = 10): 20 | self.cap = capacity 21 | # 哨兵节点, 本身不存储任何数据 22 | self.head = ListNode(None, None) 23 | self.length = 0 24 | 25 | def __len__(self): 26 | return self.length 27 | 28 | def get(self, val: object) -> bool: 29 | """ 30 | 获取指定缓存数据 31 | 思路:从链表头开始顺序遍历链表: 32 | 1. 如果此数据之前已经被缓存在链表中了,遍历得到这个数据对应的结点,并将其从原来的位置删除,然后再插入到链表的头部。 33 | 2. 如果此数据没有在缓存链表中,则将新的数据结点插入链表的头部: 34 | - 如果此时缓存已满已超过容量,则将链表尾结点删除, 35 | 参数: 36 | val:要获取的数据 37 | 返回: 38 | 存在于缓存中,返回True,否则返回 False。 39 | """ 40 | prev = None # 用于记录尾节点的前一个节点 41 | p = self.head 42 | # 如果此数据之前已经被缓存在链表中了 43 | while p.next: 44 | if p.next.val == val: 45 | # 将目标节点从原来的位置删除 46 | dest = p.next # dest临时保存目标节点 47 | p.next = dest.next 48 | # 将目标节点插入到头部 49 | self.insert_to_head(self.head, dest) 50 | return True 51 | prev = p 52 | p = p.next 53 | 54 | # 如果此数据没有缓存在链表中 55 | self.insert_to_head(self.head, ListNode(val)) 56 | self.length += 1 57 | # 添加数据导致超过容量则要删除尾节点 58 | if self.length > self.cap: 59 | prev.next = None 60 | return False 61 | 62 | @staticmethod 63 | def insert_to_head(head, node): 64 | """将指定节点插入到头部""" 65 | node.next = head.next 66 | head.next = node 67 | 68 | def __repr__(self): 69 | vals = [] 70 | p = self.head.next 71 | while p: 72 | vals.append(str(p.val)) 73 | p = p.next 74 | return '->'.join(vals) 75 | 76 | 77 | if __name__ == '__main__': 78 | cache = LRUCache(4) 79 | for n in range(40): 80 | i = random.randint(0, 7) 81 | print("cache.get(%d)" % i, cache.get(i), cache) 82 | -------------------------------------------------------------------------------- /03.linked_list/palind_rome_linkedlist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | class ListNode(object): 6 | def __init__(self, val, next=None): 7 | self.val = val 8 | self.next = next 9 | 10 | 11 | class StringLinkedList: 12 | def __init__(self, val: str): 13 | self.head = ListNode(None, None) 14 | p = self.head 15 | for ch in val: 16 | p.next = ListNode(ch) 17 | p = p.next 18 | self.head = self.head.next 19 | 20 | def is_palindrome(self) -> bool: 21 | """ 22 | 判断字符串链表是否是回文字符串 23 | 思路: 24 | - 使用快慢两个指针找到链表中点,慢指针每次前进一步,快指针每次前进两步。这样当快指针指向末尾时,慢指针指向了中点。 25 | - 在慢指针前进的过程中,同时修改其 next 指针指向上一个元素prev,使得链表前半部分反序。 26 | - 最后比较中点两侧的链表是否相等。 27 | """ 28 | p = self.head 29 | if not p.next: 30 | return True 31 | prev = None 32 | slow = p 33 | fast = p 34 | while fast and fast.next: 35 | # 快指针每次前进两步 36 | fast = fast.next.next 37 | # 慢指针每次前进一步,同时修改其 next指针指向上一个元素 38 | next_node = slow.next 39 | slow.next = prev 40 | prev = slow 41 | slow = next_node 42 | # 当快节点指向尾部时循环结束,此时慢节点指向中位点 43 | # 如果快节点仍然有值,说明字符串长度为奇数,慢节点指向中位点下一个节点 44 | mid = slow 45 | if fast: 46 | slow = slow.next 47 | 48 | # print(self.to_string(prev), self.to_string(slow), self.to_string(fast)) 49 | tmp = mid 50 | while slow: 51 | if slow.val != prev.val: 52 | return False 53 | slow = slow.next 54 | #还原倒序的链表 55 | next_node = prev.next 56 | prev.next = tmp 57 | tmp = prev 58 | prev = next_node 59 | 60 | return True 61 | 62 | @staticmethod 63 | def to_string(head: ListNode): 64 | vals = [] 65 | p = head 66 | while p: 67 | vals.append(str(p.val)) 68 | p = p.next 69 | return ''.join(vals) 70 | 71 | def __repr__(self): 72 | return self.to_string(self.head) 73 | 74 | 75 | linked_list = StringLinkedList("ecdce") 76 | print(linked_list) 77 | print(linked_list.is_palindrome()) 78 | print(linked_list) 79 | 80 | linked_list = StringLinkedList("bcddcb") 81 | print(linked_list) 82 | print(linked_list.is_palindrome()) 83 | print(linked_list) 84 | -------------------------------------------------------------------------------- /04.stack/array_stack.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | class ArrayStack(): 6 | """基于数组实现的顺序栈""" 7 | 8 | def __init__(self, n: int): 9 | self.items = [None] * n # 数组 10 | self.count = 0 # 栈中元素的个数 11 | self.n = n # 栈的大小 12 | 13 | def push(self, item) -> bool: 14 | # 数组空间不够了,直接返回 false,入栈失败。 15 | if self.count == self.n: 16 | return False 17 | # 将item放到下标为count的位置,并且count加1 18 | self.items[self.count] = item 19 | self.count += 1 20 | return True 21 | 22 | def pop(self): 23 | # 栈为空,则直接返回 None 24 | if self.count == 0: 25 | return None 26 | # 返回下标为count-1的数组元素,并且栈中元素个数count减1 27 | tmp = self.items[self.count - 1] 28 | self.count -= 1 29 | return tmp 30 | 31 | def __repr__(self): 32 | return str(self.items[:self.count]) 33 | 34 | 35 | stack = ArrayStack(3) 36 | for i in range(4): 37 | print("stack.push(%d):" % i, stack, stack.push(i)) 38 | for i in range(4): 39 | print("stack.pop():", stack, stack.pop()) 40 | -------------------------------------------------------------------------------- /04.stack/linked_stack.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | class ListNode: 6 | def __init__(self, data: int, next=None): 7 | self._data = data 8 | self._next = next 9 | 10 | 11 | class LinkedStack: 12 | """基于单链表实现的栈 13 | """ 14 | 15 | def __init__(self): 16 | self._top: ListNode = None 17 | 18 | def push(self, value): 19 | # 添加元素 20 | new_top = ListNode(value) 21 | new_top._next = self._top 22 | self._top = new_top 23 | return True 24 | 25 | def pop(self): 26 | # 删除并返回栈顶元素 27 | value = self._top._data 28 | self._top = self._top._next 29 | return value 30 | 31 | def __repr__(self) -> str: 32 | vals = [] 33 | p: ListNode = self._top 34 | while p: 35 | vals.append(str(p._data)) 36 | p = p._next 37 | return '->'.join(vals) 38 | 39 | 40 | if __name__ == "__main__": 41 | stack = LinkedStack() 42 | for i in range(4): 43 | print("stack.push(%d):" % i, stack.push(i), stack) 44 | for i in range(4): 45 | print("stack.pop():", stack.pop(), stack) 46 | -------------------------------------------------------------------------------- /04.stack/list_stack.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | class ListStack(): 6 | """基于列表实现的顺序栈""" 7 | 8 | def __init__(self): 9 | self.items = [] # 用于存储数据 10 | 11 | def push(self, item) -> bool: 12 | self.items.append(item) 13 | return True 14 | 15 | def pop(self): 16 | return self.items.pop() 17 | 18 | def __repr__(self): 19 | return str(self.items) 20 | 21 | 22 | stack = ListStack() 23 | for i in range(4): 24 | print("stack.push(%d):" % i, stack, stack.push(i)) 25 | for i in range(4): 26 | print("stack.pop():", stack, stack.pop()) 27 | -------------------------------------------------------------------------------- /04.stack/simple_browser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 实现游览器的前进后退功能 6 | 解答:使用X 和 Y两个栈,栈 X中的栈顶数据表示当前访问的页面 7 | 访问新页面时把浏览的页面依次压入栈 X,并清空栈Y。 8 | 点击后退按钮时,从栈 X 取出数据放入栈 Y。 9 | 点击前进按钮时,从栈 Y 中取出数据,放入栈 X 中。 10 | 当栈 X 中仅剩1个数据时,说明没有页面可以继续后退浏览了。 11 | 当栈 Y 中没有数据, 说明没有页面可以点击前进按钮浏览了。 12 | 13 | """ 14 | 15 | from collections import deque 16 | 17 | 18 | class Browser(): 19 | 20 | def __init__(self): 21 | self.x_stack = deque() 22 | self.y_stack = deque() 23 | 24 | def can_back(self): 25 | return len(self.x_stack) > 1 26 | 27 | def can_forward(self): 28 | return len(self.y_stack) > 0 29 | 30 | def open(self, url): 31 | print("Open new url %s" % url, end="\n") 32 | self.x_stack.appendleft(url) 33 | self.y_stack.clear() 34 | 35 | def back(self): 36 | if self.can_back(): 37 | self.y_stack.appendleft(self.x_stack.popleft()) 38 | print("back to %s" % self.x_stack[0], end="\n") 39 | 40 | def forward(self): 41 | if self.can_forward(): 42 | self.x_stack.appendleft(self.y_stack.popleft()) 43 | print("forward to %s" % self.x_stack[0], end="\n") 44 | 45 | def __repr__(self): 46 | return "X:HEAD=>%s,Y:HEAD=>%s" % ("->".join(self.x_stack) or "None", "->".join(self.y_stack) or "None") 47 | 48 | if __name__ == '__main__': 49 | browser = Browser() 50 | print("顺序查看了 a,b,c 三个页面") 51 | browser.open('a') 52 | browser.open('b') 53 | browser.open('c') 54 | print(browser) 55 | print("点击两次后退按钮") 56 | browser.back() 57 | browser.back() 58 | print(browser) 59 | print("又点击一次前进按钮") 60 | browser.forward() 61 | print(browser) 62 | print("访问新页面 d") 63 | browser.open('d') 64 | print(browser) 65 | -------------------------------------------------------------------------------- /05.queue/array_queue.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional 5 | 6 | 7 | class ArrayQueue: 8 | """用数组实现的队列""" 9 | 10 | def __init__(self, capacity: int): 11 | self.items: list = [None] * capacity 12 | self.capacity = capacity 13 | self.head = 0 # 队头下标 14 | self.tail = 0 # 队尾下标 15 | 16 | def enqueue(self, item: str) -> bool: 17 | """入队""" 18 | if self.tail == self.capacity: 19 | return False 20 | self.items[self.tail] = item 21 | self.tail += 1 22 | return True 23 | 24 | def dequeue(self) -> Optional[str]: 25 | """出队""" 26 | if self.head == self.tail: 27 | return None 28 | item = self.items[self.head] 29 | self.head += 1 30 | return item 31 | 32 | def __repr__(self) -> str: 33 | return str(self.items[self.head:self.tail]) 34 | 35 | 36 | if __name__ == "__main__": 37 | q = ArrayQueue(10) 38 | for i in range(10): 39 | q.enqueue(str(i)) 40 | print(q) 41 | 42 | for _ in range(3): 43 | q.dequeue() 44 | print(q) 45 | 46 | q.enqueue("7") 47 | q.enqueue("8") 48 | print(q) 49 | -------------------------------------------------------------------------------- /05.queue/blocking_queue.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import queue 5 | import random 6 | import threading 7 | import time 8 | 9 | 10 | class Producer(threading.Thread): 11 | nameList = ["apple", "peach", "pineapple", "orange", "banana", "blueberry"] 12 | flag = 1 13 | 14 | def __init__(self, q, name): 15 | threading.Thread.__init__(self) 16 | self.name = name 17 | self.q = q 18 | 19 | def run(self): 20 | name_list = Producer.nameList 21 | while Producer.flag: 22 | queueLock.acquire() 23 | if not self.q.full(): 24 | data = name_list[random.randrange(0, len(name_list))] 25 | self.q.put(data) 26 | print("%s 生产数据: %s" % (threading.currentThread().name, data)) 27 | queueLock.release() 28 | else: 29 | queueLock.release() 30 | time.sleep(random.random() * 3) 31 | 32 | 33 | class Consumer(threading.Thread): 34 | flag = 1 35 | 36 | def __init__(self, q, name): 37 | threading.Thread.__init__(self) 38 | self.name = name 39 | self.q = q 40 | 41 | def run(self): 42 | while Consumer.flag: 43 | queueLock.acquire() 44 | if not self.q.is_empty(): 45 | data = self.q.get() 46 | print("%s 消费数据: %s" % (threading.currentThread().name, data)) 47 | queueLock.release() 48 | else: 49 | queueLock.release() 50 | time.sleep(random.random() * 4) 51 | 52 | 53 | workQueue = queue.Queue(5) 54 | queueLock = threading.Lock() 55 | # 创建新线程 56 | Producer(workQueue, "Producer1").start() 57 | Producer(workQueue, "Producer2").start() 58 | Consumer(workQueue, "Consumer1").start() 59 | Consumer(workQueue, "Consumer2").start() 60 | Consumer(workQueue, "Consumer3").start() 61 | 62 | while 1: 63 | time.sleep(1) 64 | print(workQueue.queue) -------------------------------------------------------------------------------- /05.queue/circular_queue.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional 5 | 6 | 7 | class CircularQueue: 8 | def __init__(self, capacity): 9 | self.capacity = capacity + 1 10 | self.items = [None] * self.capacity 11 | self.head = 0 # head表示队头下标 12 | self.tail = 0 # tail表示队尾下标 13 | 14 | def enqueue(self, item: str) -> bool: 15 | """入队""" 16 | if (self.tail + 1) % self.capacity == self.head: 17 | return False 18 | self.items[self.tail] = item 19 | self.tail = (self.tail + 1) % self.capacity 20 | return True 21 | 22 | def dequeue(self) -> Optional[str]: 23 | # 如果head == tail 表示队列为空 24 | if self.head == self.tail: return None 25 | item = self.items[self.head] 26 | self.head = (self.head + 1) % self.capacity 27 | return item 28 | 29 | def __repr__(self) -> str: 30 | if self.tail >= self.head: 31 | return str(self.items[self.head: self.tail]) 32 | else: 33 | return str(self.items[self.head:] + self.items[:self.tail]) 34 | 35 | 36 | if __name__ == "__main__": 37 | q = CircularQueue(5) 38 | for i in range(5): 39 | q.enqueue(str(i)) 40 | q.dequeue() 41 | q.dequeue() 42 | q.enqueue(str(5)) 43 | print(q) 44 | -------------------------------------------------------------------------------- /05.queue/dynamic_array_queue.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional 5 | 6 | 7 | class DynamicArrayQueue: 8 | """用数组实现的队列""" 9 | 10 | def __init__(self, capacity: int): 11 | self.items: list = [None] * capacity 12 | self.capacity = capacity 13 | self.head = 0 # 队头下标 14 | self.tail = 0 # 队尾下标 15 | 16 | def enqueue(self, item: str) -> bool: 17 | """入队""" 18 | # 表示队列末尾没有空间了 19 | if self.tail == self.capacity: 20 | if self.head == 0: return False 21 | # 数据搬移 22 | for i in range(self.head, self.tail): 23 | self.items[i - self.head] = self.items[i] 24 | # 搬移完之后重新更新 head 和 tail 25 | self.tail -= self.head 26 | self.head = 0 27 | self.items[self.tail] = item 28 | self.tail += 1 29 | return True 30 | 31 | def dequeue(self) -> Optional[str]: 32 | """出队""" 33 | if self.head == self.tail: 34 | return None 35 | item = self.items[self.head] 36 | self.head += 1 37 | return item 38 | 39 | def __repr__(self) -> str: 40 | return str(self.items[self.head:self.tail]) 41 | 42 | 43 | if __name__ == "__main__": 44 | q = DynamicArrayQueue(10) 45 | for i in range(10): 46 | q.enqueue(str(i)) 47 | print(q) 48 | 49 | for _ in range(3): 50 | q.dequeue() 51 | print(q) 52 | 53 | q.enqueue("7") 54 | q.enqueue("8") 55 | print(q) 56 | -------------------------------------------------------------------------------- /05.queue/linked_queue.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional 5 | 6 | 7 | class ListNode: 8 | 9 | def __init__(self, data: str, next=None): 10 | self.data = data 11 | self._next = next 12 | 13 | 14 | class LinkedQueue: 15 | 16 | def __init__(self): 17 | self._head: Optional[ListNode] = None 18 | self._tail: Optional[ListNode] = None 19 | 20 | def enqueue(self, value: str): 21 | # 入队 22 | new_node = ListNode(value) 23 | if self._tail: 24 | self._tail._next = new_node 25 | else: 26 | self._head = new_node 27 | self._tail = new_node 28 | 29 | def dequeue(self) -> Optional[str]: 30 | """出队""" 31 | if self._head: 32 | value = self._head.data 33 | self._head = self._head._next 34 | if not self._head: 35 | self._tail = None 36 | return value 37 | 38 | def __repr__(self) -> str: 39 | values = [] 40 | p: ListNode = self._head 41 | while p: 42 | values.append(p.data) 43 | p = p._next 44 | return "->".join(values) 45 | 46 | 47 | if __name__ == "__main__": 48 | q = LinkedQueue() 49 | for i in range(10): 50 | q.enqueue(str(i)) 51 | print(q) 52 | 53 | for _ in range(3): 54 | q.dequeue() 55 | print(q) 56 | 57 | q.enqueue("7") 58 | q.enqueue("8") 59 | print(q) 60 | -------------------------------------------------------------------------------- /06.recursion/combination_str.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 原始字符串是"abc": 6 | 打印组合combination情况: 7 | "a" "b" "c" "ab" "ac" "bc" "abc" 8 | """ 9 | def combinationStr(string): 10 | temp = [] 11 | result = [] 12 | 13 | def combination(chars, pos, num): 14 | if num == 0: 15 | result.append("".join(temp)) 16 | return 17 | if pos == len(chars): 18 | return 19 | temp.append(chars[pos]) 20 | combination(chars, pos + 1, num - 1) 21 | temp.pop(len(temp) - 1) 22 | combination(chars, pos + 1, num) 23 | 24 | chars = list(string) 25 | for i in range(1, len(chars) + 1): 26 | combination(chars, 0, i) 27 | return result 28 | 29 | print(combinationStr("abc")) 30 | -------------------------------------------------------------------------------- /06.recursion/fibonacci_sequence.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def fib(n): 6 | if n <= 1: 7 | return n 8 | return fib(n - 1) + fib(n - 2) 9 | 10 | 11 | # 输出了第10个斐波那契数列 12 | print("斐波那契数列:") 13 | for i in range(10): 14 | print(fib(i), end=",") 15 | -------------------------------------------------------------------------------- /06.recursion/find_root_referrer_id.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import pymysql 5 | 6 | db = pymysql.connect("localhost", "root", "root", "test_db") 7 | cursor = db.cursor() 8 | 9 | 10 | def find_root_referrer_id(actorId: int, relation=None): 11 | if relation is None: 12 | relation = set() 13 | relation.add(actorId) 14 | referrerId = cursor.execute(r"select referrer_id from user_info where actor_id = %s", actorId) 15 | if referrerId in relation or referrerId == None: 16 | return actorId 17 | return find_root_referrer_id(referrerId) 18 | 19 | find_root_referrer_id(1) 20 | 21 | cursor.close() 22 | db.close() 23 | -------------------------------------------------------------------------------- /06.recursion/perm_com_str.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 编程列出一个任意长度字符串的全字符排列组合情况,原始字符串中没有重复字符 6 | 例如: 7 | 原始字符串是"abc",打印得到下列所有排列组合情况 8 | "a" "b" "c" 9 | "ab" "bc" "ca" "ba" "cb" "ac" 10 | "abc" "acb" "bac" "bca" "cab" "cba" 11 | 12 | 思路分析: 13 | 每行字符个数都是递增 ,下一行的字符是建立在上一行的基础上得到的 14 | 即在将第一行字符串长度限定为1,第二行为2...., 15 | 在第一行数据基础上{a,b,c},创建第二行数据, 16 | 遍历字符串中所字符,并与第一行数据组合。注意每行字符串长度限制 17 | 1、先将原始字符串转换成字符数组ch 18 | 2、将原始字符串每个字符添加到list集合中 19 | 3、遍历list集合用每个元素str去查找是否存在数组ch中的元素,如果ch中的字符c没有被str找到则用str+c作为新集合的值返回; 20 | 4、遍历新集合重复3步骤 21 | """ 22 | 23 | 24 | def permComStr(chars): 25 | # 将一个list用chars衍生,例如列表['a', 'b', 'c']会衍生出['ab', 'ac', 'ba', 'bc', 'ca', 'cb'] 26 | def getDeriveList(srcList): 27 | if len(srcList) == 0: return list(chars) 28 | newList = [] 29 | for str in srcList: 30 | for c in chars: 31 | if str.skip_list_find(c) == -1: 32 | newList.append(str + c) 33 | return newList 34 | 35 | # 初始化用于衍生的list 36 | deriveList = [] 37 | # 共需衍生len(chars)次 38 | for i in range(len(chars)): 39 | # 衍生list 40 | deriveList = getDeriveList(deriveList) 41 | print(" ".join(deriveList)) 42 | 43 | 44 | permComStr("abcd") 45 | -------------------------------------------------------------------------------- /06.recursion/permutation_str.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 编程列出一个任意长度字符串的全字符排序情况,原始字符串中没有重复字符 6 | 例如: 7 | 原始字符串是"abc": 8 | 打印所有的排列permutation情况: 9 | "abc" "acb" "bac" "bca" "cab" "cba" 10 | """ 11 | 12 | 13 | def permutationStr(str): 14 | result = [] 15 | 16 | def permutation(chars, begin): 17 | if begin == len(chars): 18 | result.append("".join(chars)) 19 | return 20 | for j in range(begin, len(chars)): 21 | chars[begin], chars[j] = chars[j], chars[begin] 22 | permutation(chars, begin + 1) 23 | chars[begin], chars[j] = chars[j], chars[begin] 24 | 25 | permutation(list(str), 0) 26 | return result 27 | 28 | 29 | print(permutationStr("abcd")) 30 | -------------------------------------------------------------------------------- /06.recursion/tree_dir.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import os 5 | def tree_dir(dir, layer=0): 6 | listdir = os.listdir(dir) 7 | for index, file in enumerate(listdir): 8 | file_path = os.path.join(dir, file) 9 | print("| " * (layer - 1), end="") 10 | if (layer > 0): 11 | print("`--" if index == len(listdir) - 1 else "|--", end="") 12 | print(file) 13 | if (os.path.isdir(file_path)): 14 | tree_dir(file_path, layer + 1) 15 | 16 | tree_dir("..") 17 | -------------------------------------------------------------------------------- /07.sorts/bubble_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import List 5 | 6 | 7 | def bubble_sort(arr: List[int], n: int): 8 | """冒泡排序,arr是数组,n表示数组长度""" 9 | if n <= 1: return 10 | for i in range(n): 11 | # 提前退出标志位 12 | flag = False 13 | for j in range(n - i - 1): 14 | if (arr[j] > arr[j + 1]): 15 | arr[j], arr[j + 1] = arr[j + 1], arr[j] # 交换 16 | flag = True # 此次冒泡有数据交换 17 | if not flag: break 18 | 19 | 20 | -------------------------------------------------------------------------------- /07.sorts/bucket_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import math 5 | 6 | 7 | # m表示桶的个数 8 | def bucket_sort(arr: list, m: int): 9 | if len(arr) < 2: return 10 | # 扫描最小值和最大值 11 | min, max = arr[0], arr[0] 12 | for i in range(0, len(arr)): 13 | if arr[i] < min: 14 | min = arr[i] 15 | elif arr[i] > max: 16 | max = arr[i] 17 | bucket_size = math.ceil((max - min + 1) / m) 18 | buckets = [] 19 | for i in range(m): 20 | buckets.append([]) 21 | # 将数组中值分配到各个桶里 22 | for data in arr: 23 | bucket_index = (data - min) // bucket_size 24 | buckets[bucket_index].append(data) 25 | # 对每个桶进行排序,时间复杂度小于O(nlogn)的排序算法都可以 26 | k = 0 27 | for bucket in buckets: 28 | bucket.sort() 29 | for data in bucket: 30 | arr[k] = data 31 | k += 1 32 | 33 | 34 | if __name__ == "__main__": 35 | a3 = [2, 5, 3, 0, 2, 3, 0, 3, 0, 4, 4, 5, 1, 7, 8, 9] 36 | print(a3) 37 | bucket_sort(a3, 4) 38 | print(a3) 39 | -------------------------------------------------------------------------------- /07.sorts/counting_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import List 5 | 6 | 7 | # 对每个分数进行计数 8 | def get_counts(arr: List[int]) -> List[int]: 9 | counts = [0] * (max(arr) + 1) 10 | for num in arr: 11 | counts[num] += 1 12 | return counts 13 | 14 | 15 | # 简单的计数排序 16 | def counting_sort_simple(arr: List[int]): 17 | if len(arr) <= 1: return 18 | counts = get_counts(arr) 19 | k = 0 20 | for i in range(len(counts)): 21 | count = counts[i] 22 | for j in range(count): 23 | arr[k] = i 24 | k += 1 25 | 26 | 27 | # 便于获得指定数值的在有序数组中对应的存储位置 28 | def get_sum_counts(arr: List[int]) -> List[int]: 29 | counts = [0] * (max(arr) + 1) 30 | for num in arr: 31 | counts[num] += 1 32 | for num in range(1, len(counts)): 33 | counts[num] += counts[num - 1] 34 | return counts 35 | 36 | 37 | # 计数排序 38 | def counting_sort(arr: List[int]) -> List[int]: 39 | n = len(arr) 40 | if n <= 1: return arr 41 | counts = get_sum_counts(arr) 42 | r = [0] * n 43 | # 遍历数组arr,对于被遍历的数据去数组C中取出对应角标的值,比如遍历到3时,从数组C中取出角标为3的值7。 44 | # 然后把被遍历的数据放入临时数组R角标为7-1的位置中,数组C中对应角标位置的值减1。 45 | for i in range(len(arr), -1, -1): 46 | data = arr[i] 47 | r[counts[data] - 1] = data 48 | counts[data] -= 1 49 | return r 50 | 51 | 52 | if __name__ == "__main__": 53 | a3 = [2, 5, 3, 0, 2, 3, 0, 3] 54 | r = counting_sort(a3) 55 | print(a3) 56 | counting_sort_simple(a3) 57 | print(a3) 58 | print(r) 59 | -------------------------------------------------------------------------------- /07.sorts/insertion_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def insertion_sort(arr): 6 | for i in range(1, len(arr)): 7 | value = arr[i] # 待插入元素,arr[0:i-1]作为有序序列 8 | j = i - 1 # j指向有序序列的末端 9 | while j >= 0 and arr[j] > value: 10 | arr[j + 1] = arr[j] 11 | j -= 1 12 | arr[j + 1] = value # 插入数据 -------------------------------------------------------------------------------- /07.sorts/kth_smallest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import random 5 | 6 | 7 | def partition(arr, p, r): 8 | # 随机选取基准值, 并将基准值替换到数组第一个元素 9 | q = random.randint(p, r) 10 | arr[p], arr[q] = arr[q], arr[p] 11 | pivot = arr[p] 12 | while p < r: 13 | # 从右向左查找比基准值小的位置 14 | while p < r and arr[r] >= pivot: r -= 1 15 | arr[p] = arr[r] 16 | # 从左向右查找比基准值大的位置 17 | while p < r and arr[p] <= pivot: p += 1 18 | arr[r] = arr[p] 19 | arr[p] = pivot 20 | return p 21 | 22 | 23 | def kth_smallest(arr: list, k: int): 24 | if len(arr) < k: return -1 25 | q = partition(arr, 0, len(arr) - 1) 26 | while q != k - 1: 27 | if q < k - 1: 28 | q = partition(arr, q + 1, len(arr) - 1) 29 | else: 30 | q = partition(arr, 0, q - 1) 31 | return arr[q] 32 | -------------------------------------------------------------------------------- /07.sorts/logfile_merge.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys 5 | 6 | fs = [] 7 | data = [] 8 | out = open("out.log", "w", buffering=300 * 1024 * 1024) 9 | for i in range(10): 10 | fs.append(open("../logs/%s.log" % i, buffering=50 * 1024 * 1024)) 11 | data.append(fs[i].readline().rstrip()) 12 | 13 | while True: 14 | min = 0 15 | for i in range(1, 10): 16 | if int(data[min]) > int(data[i]): 17 | min = i 18 | if data[min] == sys.maxsize: break 19 | out.write(data[min]) 20 | out.write("\n") 21 | line = fs[min].readline().rstrip() 22 | if line: 23 | data[min] = line 24 | else: 25 | data[min] = sys.maxsize 26 | 27 | for f in fs: 28 | f.close() 29 | out.close() -------------------------------------------------------------------------------- /07.sorts/merge_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys 5 | 6 | 7 | def merge(arr, p, q, r): 8 | i, j, k = p, q + 1, 0 # 初始化变量 i, j, k 9 | tmp = [0] * (r - p + 1) # 申请一个大小跟arr[p:r+1]一样的临时数组 10 | while i <= q and j <= r: 11 | if arr[i] <= arr[j]: 12 | tmp[k] = arr[i] 13 | i += 1 14 | else: 15 | tmp[k] = arr[j] 16 | j += 1 17 | k += 1 18 | # 判断哪个子数组中有剩余的数据 19 | start, end = i, q 20 | if j <= r: start, end = j, r 21 | # 将剩余的数据拷贝到临时数组tmp 22 | while start <= end: 23 | tmp[k] = arr[start] 24 | k += 1 25 | start += 1 26 | # 将tmp中的数组拷贝回 arr[p:r+1] 27 | arr[p: r + 1] = tmp 28 | 29 | 30 | def merge_by_sentry(arr, p, q, r): 31 | n1, n2 = q - p + 1, r - q # 表示两个子数组的长度 32 | # 需要一个位置存储哨兵,所以临时数组长度是 子数组长度+1 33 | L = [0] * (n1 + 1) 34 | R = [0] * (n2 + 1) 35 | # 拷贝数据到临时数组 L[] 和 R[] 36 | for i in range(0, n1): 37 | L[i] = arr[p + i] 38 | L[n1] = sys.maxsize # 第一个数组添加哨兵(最大值) 39 | for j in range(0, n2): 40 | R[j] = arr[q + 1 + j] 41 | R[n2] = sys.maxsize # 第二个数组添加哨兵(最大值) 42 | # 归并临时数组到 arr[l..r] 43 | i, j, k = 0, 0, p # 初始化变量 i, j, k 44 | while k <= r: 45 | # 当左边数组到达哨兵值时,i不再增加,直到右边数组读取完剩余值,同理右边数组也一样 46 | if L[i] <= R[j]: 47 | arr[k] = L[i] 48 | i += 1 49 | else: 50 | arr[k] = R[j] 51 | j += 1 52 | k += 1 53 | 54 | 55 | def merge_sort(arr, p, r): 56 | if p >= r: 57 | return 58 | q = (p + r) >> 1 59 | merge_sort(arr, p, q) 60 | merge_sort(arr, q + 1, r) 61 | merge(arr, p, q, r) 62 | 63 | 64 | if __name__ == "__main__": 65 | # array = [3, 4, 2, 1, 5, 6, 7, 9, 10, 8] 66 | array = [5, 0, 4, 2, 3, 1, 3, 3, 3, 6, 8, 7] 67 | merge_sort(array, 0, len(array) - 1) 68 | print(array) 69 | -------------------------------------------------------------------------------- /07.sorts/quick_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import random 5 | 6 | 7 | def partition(arr: list, p, r): 8 | i, pivot = p, arr[r] 9 | for j in range(p, r): 10 | if arr[j] < pivot: 11 | if i != j: 12 | arr[i], arr[j] = arr[j], arr[i] 13 | i += 1 14 | arr[i], arr[r] = arr[r], arr[i] 15 | return i 16 | 17 | 18 | def partition_two_way(arr, p, r): 19 | # 随机选取基准值, 并将基准值替换到数组第一个元素 20 | q = random.randint(p, r) 21 | arr[p], arr[q] = arr[q], arr[p] 22 | pivot = arr[p] 23 | while p < r: 24 | # 从右向左查找比基准值小的位置 25 | while p < r and arr[r] >= pivot: r -= 1 26 | arr[p] = arr[r] 27 | # 从左向右查找比基准值大的位置 28 | while p < r and arr[p] <= pivot: p += 1 29 | arr[r] = arr[p] 30 | arr[p] = pivot 31 | return p 32 | 33 | 34 | def quick_sort(arr, p, r): 35 | if p >= r: return 36 | q = partition(arr, p, r) 37 | quick_sort(arr, p, q - 1) 38 | quick_sort(arr, q + 1, r) 39 | 40 | 41 | a4 = [5, -1, 9, 3, 7, 8, 3, -2, 9] 42 | quick_sort(a4, 0, len(a4) - 1) 43 | print(a4) 44 | -------------------------------------------------------------------------------- /07.sorts/quick_user_sort_by_age.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | # 桶排序 6 | def quick_user_sort_by_age(user_list: list, fn=lambda x: int(x)): 7 | n = len(user_list) 8 | if n <= 1: return user_list 9 | # 便于获得指定数值的在有序数组中对应的存储位置 10 | buckets = [] 11 | for i in range(121): 12 | buckets.append([]) 13 | for data in user_list: 14 | buckets[fn(data)].append(data) 15 | k = 0 16 | for bucket in buckets: 17 | for data in bucket: 18 | user_list[k] = data 19 | k += 1 20 | -------------------------------------------------------------------------------- /07.sorts/radix_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def radix_sort(arr): 6 | max = arr[0] 7 | for i in range(len(arr)): 8 | if arr[i] > max: 9 | max = arr[i] 10 | max_len = len(str(max)) 11 | # 从个位开始(保证稳定性),对数组每一位都进行一次计数排序 12 | for i in range(max_len): 13 | exp = 10 ** i 14 | arr = counting_sort(arr, exp) 15 | print(arr) 16 | return arr 17 | 18 | 19 | def counting_sort(arr, exp): 20 | if len(arr) <= 1: return 21 | # 计算每个元素的个数 22 | counts = [0] * 10 23 | for data in arr: 24 | counts[(data // exp) % 10] += 1 25 | # 计算排序后的位置 26 | for i in range(1, len(counts)): 27 | counts[i] += counts[i - 1] 28 | # 临时数组r,存储排序之后的结果 29 | r = [0] * len(arr) 30 | for i in range(len(arr) - 1, -1, -1): 31 | j = (arr[i] // exp) % 10 32 | r[counts[j] - 1] = arr[i] 33 | counts[j] -= 1 34 | return r 35 | 36 | 37 | if __name__ == "__main__": 38 | a3 = [234, 567, 123, 20, 12, 3453, 40, 93] 39 | print(a3) 40 | r = radix_sort(a3) 41 | print(r) 42 | -------------------------------------------------------------------------------- /07.sorts/selection_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import List 5 | 6 | 7 | def selection_sort(arr): 8 | for i in range(len(arr) - 1): 9 | min = i 10 | for j in range(i + 1, len(arr)): 11 | if (arr[min] > arr[j]): min = j 12 | arr[i], arr[min] = arr[min], arr[i] 13 | return arr 14 | 15 | arr = [3, 4, 2, 1, 5, 6, 7, 8] 16 | selection_sort(arr) 17 | print(arr) 18 | -------------------------------------------------------------------------------- /07.sorts/shell_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def shell_sort(arr): 6 | incr = len(arr) // 2 7 | while incr > 0: 8 | # i 表示待插入元素角标,arr[0:i:incr]将作为有序序列 9 | # 例如有序序列角标为{0,incr,2*incr,...,i-incr},待插入元素角标为i,{n*incr} 10 | for i in range(incr, len(arr), incr): 11 | key = arr[i] # 待插入元素,arr[0:i:incr]作为有序序列 12 | j = i - incr # j指向有序序列的末端 13 | while j >= 0 and arr[j] > key: 14 | arr[j + incr] = arr[j] 15 | j -= incr 16 | arr[j + incr] = key 17 | incr //= 2 18 | 19 | -------------------------------------------------------------------------------- /07.sorts/string_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | # 桶排序 6 | def string_sort(s: str): 7 | # 便于获得指定数值的在有序数组中对应的存储位置 8 | buckets = [[], [], []] 9 | i = 0 10 | for ch in s: 11 | if ch.islower(): 12 | buckets[0].append(ch) 13 | elif ch.isnumeric(): 14 | buckets[1].append(ch) 15 | elif ch.isupper(): 16 | buckets[2].append(ch) 17 | print(ch, i) 18 | print(buckets) 19 | result = [] 20 | for bucket in buckets: 21 | for data in bucket: 22 | result.append(data) 23 | return "".join(result) 24 | 25 | 26 | print(string_sort("D,a,F,B,c,A,z")) 27 | -------------------------------------------------------------------------------- /09.binary_search/binary_search_circle_array.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def binary_search_circle_array(arr: list, value) -> int: 6 | low, high = 0, len(arr) - 1 7 | while low <= high: 8 | mid = (low + high) >> 1 9 | if arr[mid] == value: return mid 10 | # 上面没有返回,说明中间值不是目标值 11 | if arr[mid] < arr[high]: # 若中间数小于最右边数,则右半段是升序区间 12 | if arr[mid] < value and value <= arr[high]: # 在右半段有序区间 13 | low = mid + 1 14 | else: 15 | high = mid - 1 16 | elif arr[mid] > arr[high]: # 若中间数大于最右边数,则左半段是升序区间 17 | if arr[low] <= value and value < arr[mid]: # 在左半段有序区间 18 | high = mid - 1 19 | else: 20 | low = mid + 1 21 | else: # 若中间数等于最右边数,则目标不在右半段 22 | high = mid - 1 23 | return -1 24 | 25 | 26 | for i in range(0, 9): 27 | v = binary_search_circle_array([4, 5, 6, 1, 2, 3], i) 28 | print(v) 29 | -------------------------------------------------------------------------------- /09.binary_search/bsearch_sqrt.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import math 5 | 6 | 7 | def bsearch_sqrt(num: float) -> float: 8 | if num < 0: 9 | raise ValueError 10 | if num ** 2 == num: 11 | return num 12 | if num < 1: 13 | low, high = num, 1 14 | else: 15 | low, high = 0, num 16 | while high - low > 0.0000001: 17 | mid = (high + low) / 2 18 | mid_v2 = mid ** 2 19 | if mid_v2 > num: 20 | high = mid 21 | elif mid_v2 < num: 22 | low = mid 23 | elif mid_v2 == num: 24 | return mid 25 | return round((high + low) / 2, 6) 26 | 27 | 28 | for i in range(2001): 29 | num = i / 1000 30 | print(num, math.sqrt(num), bsearch_sqrt(num)) 31 | -------------------------------------------------------------------------------- /09.binary_search/ip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | ip_rule_list = [] 5 | with open("ip.txt", encoding="utf-8") as f: 6 | for line in f: 7 | start_ip, end_ip, location = line.rstrip().split("|", 2) 8 | ip_rule_list.append((start_ip, end_ip, location)) 9 | 10 | 11 | def ip2int(ip_str: str) -> int: 12 | result = 0 13 | for i in ip_str.split("."): 14 | result = (result << 8) | int(i) 15 | return result 16 | 17 | 18 | ip_rule_list.sort(key=lambda x: ip2int(x[0])) 19 | 20 | 21 | def ip_to_location(ip: str) -> str: 22 | low, high = 0, len(ip_rule_list) - 1 23 | ip_int = ip2int(ip) 24 | while low <= high: 25 | mid = (low + high) >> 1 26 | # 查找最后一个起始IP小于等于这个IP的IP区间 27 | if ip2int(ip_rule_list[mid][0]) < ip_int: 28 | low = mid + 1 29 | else: 30 | high = mid - 1 31 | if high >= 0 and ip2int(ip_rule_list[high][0]) <= ip_int <= ip2int(ip_rule_list[high][1]): 32 | return ip_rule_list[high][2] 33 | else: 34 | return "" 35 | 36 | 37 | to_location = ip_to_location("218.25.46.4") 38 | print(to_location) 39 | 40 | # and ip2int(ip) <= ip2int(ip_rule_list[high][1]) 41 | -------------------------------------------------------------------------------- /11.hash_table/LRUCacheHashTable.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional 5 | 6 | 7 | class DNode(): 8 | def __init__(self, key=None, value=None): 9 | self.key = key 10 | self.value = value 11 | self.prev: Optional[DNode] = None 12 | self.next: Optional[DNode] = None 13 | 14 | 15 | class LRUCacheHashTable(): 16 | def __init__(self, capacity=10): 17 | self.length = 0 # 链表长度 18 | self.capacity = capacity # 链表容量 19 | self.table = {} # 散列表存储key 20 | # 创建哨兵节点 21 | self.head_node = DNode() 22 | self.tail_node = DNode() 23 | self.head_node.next = self.tail_node 24 | self.tail_node.prev = self.head_node 25 | 26 | def put(self, key, value): 27 | node: DNode = self.table.get(key) 28 | if node is None: 29 | new_node = DNode(key, value) 30 | self.table[key] = new_node 31 | self.add_node(new_node) 32 | self.length += 1 33 | if self.length > self.capacity: 34 | tail = self.pop_tail() 35 | del self.table[tail.key] 36 | self.length -= 1 37 | else: 38 | node.value = value 39 | self.move_to_head(node) 40 | 41 | def add_node(self, new_node: DNode): 42 | """将新节点加到头部""" 43 | new_node.next = self.head_node.next 44 | new_node.prev = self.head_node 45 | self.head_node.next.prev = new_node 46 | self.head_node.next = new_node 47 | 48 | def pop_tail(self): 49 | """弹出尾部数据节点""" 50 | node = self.tail_node.prev 51 | self.remove_node(node) 52 | return node 53 | 54 | @staticmethod 55 | def remove_node(node): 56 | """移除节点""" 57 | node.prev.next = node.next 58 | node.next.prev = node.prev 59 | 60 | def move_to_head(self, node): 61 | """将节点移动到头部""" 62 | self.remove_node(node) 63 | self.add_node(node) 64 | 65 | def get(self, key): 66 | """获取节点数据""" 67 | node: DNode = self.table.get(key) 68 | if node is None: return None 69 | self.move_to_head(node) 70 | return node.value 71 | 72 | def remove(self, key): 73 | """移除节点数据""" 74 | node = self.table.get(key) 75 | if node is None: return 76 | self.remove_node(node) 77 | self.length -= 1 78 | 79 | def __repr__(self): 80 | p = self.head_node.next 81 | result = [] 82 | while p.next: 83 | result.append("%s:%s" % (p.key, p.value)) 84 | p = p.next 85 | return "{%s}" % ", ".join(result) 86 | 87 | 88 | if __name__ == "__main__": 89 | map = LRUCacheHashTable() 90 | for i in range(100): 91 | map.put(i, 100 - i) 92 | print(map) 93 | for i in range(5, 96): 94 | map.remove(i) 95 | map.put("aa", 1) 96 | print(map.get(96)) 97 | print(map) 98 | -------------------------------------------------------------------------------- /11.hash_table/common_string.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | arr1 = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] 5 | arr2 = ['apple', 'apple', 'pear', 'banana', 'Apricot','Avocado'] 6 | common_str = set(arr1) & set(arr2) 7 | print(common_str) 8 | 9 | -------------------------------------------------------------------------------- /11.hash_table/hash_code.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def hash_code(s: str) -> int: 6 | result = 0 7 | base = ord('a') 8 | for ch in s.lower(): 9 | result = result * 26 + (ord(ch) - base) 10 | return result 11 | 12 | 13 | print(hash_code("abc")) 14 | -------------------------------------------------------------------------------- /11.hash_table/url_count_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | url_count_dict = {} 5 | k = 0 6 | with open("access.log", "r") as f: 7 | for line in f: 8 | url = line.rstrip() 9 | if len(url) > 0: 10 | value = url_count_dict.setdefault(url, 0) + 1 11 | url_count_dict[url] = value 12 | if value > k: k = value 13 | result = [] 14 | # k不大可以使用桶排序,每个次数一个桶 15 | if k < 10: 16 | buckets = [] 17 | for i in range(k): 18 | buckets.append([]) 19 | # 将数组中值分配到各个桶里 20 | for url, value in url_count_dict.items(): 21 | buckets[value - 1].append(url) 22 | for value in range(len(buckets) - 1, -1, -1): 23 | for url in buckets[value]: 24 | result.append((url, value + 1)) 25 | else: 26 | result = sorted(url_count_dict.items(), key=lambda x: x[1], reverse=True) 27 | 28 | for x in result[0:10]: 29 | print(x) 30 | -------------------------------------------------------------------------------- /13.binary_tree/binary_tree.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import Optional, List 5 | 6 | 7 | class TreeNode(): 8 | def __init__(self, value): 9 | self.val = value 10 | self.left = None 11 | self.right = None 12 | 13 | 14 | # 前序遍历 15 | def pre_order(root: Optional[TreeNode]): 16 | if root: 17 | yield root.val 18 | yield from pre_order(root.left) 19 | yield from pre_order(root.right) 20 | 21 | 22 | # 中序遍历 23 | def in_order(root: Optional[TreeNode]): 24 | if root: 25 | yield from in_order(root.left) 26 | yield root.val 27 | yield from in_order(root.right) 28 | 29 | 30 | # 后序遍历 31 | def post_order(root: Optional[TreeNode]): 32 | if root: 33 | yield from post_order(root.left) 34 | yield from post_order(root.right) 35 | yield root.val 36 | 37 | 38 | from collections import deque 39 | 40 | 41 | # 层级遍历 42 | def layer_order(root: TreeNode): 43 | if not root: return 44 | queue = deque([root]) 45 | while queue: 46 | e: TreeNode = queue.popleft() 47 | yield e.val 48 | if e.left: queue.append(e.left) 49 | if e.right: queue.append(e.right) 50 | 51 | 52 | def level_order(root: TreeNode) -> List[List]: 53 | levels = [] 54 | if not root: 55 | return levels 56 | level = 0 57 | queue = deque([root]) 58 | while queue: 59 | levels.append([]) 60 | for i in range(len(queue)): 61 | node = queue.popleft() 62 | levels[level].append(node.val) 63 | if node.left: 64 | queue.append(node.left) 65 | if node.right: 66 | queue.append(node.right) 67 | level += 1 68 | 69 | return levels 70 | 71 | 72 | # 根节点高度=max(左子树高度,右子树高度)+1 73 | def get_level(node: TreeNode) -> int: 74 | if node is None: return 0 75 | return max(get_level(node.left), get_level(node.right)) + 1 76 | 77 | 78 | if __name__ == "__main__": 79 | root = TreeNode("root") 80 | 81 | l1 = TreeNode("l1") 82 | r1 = TreeNode("r1") 83 | 84 | l1_l2 = TreeNode("l1_l2") 85 | l1_r2 = TreeNode("l1_r2") 86 | r1_l2 = TreeNode("r1_l2") 87 | r1_r2 = TreeNode("r1_r2") 88 | 89 | l1_l2_l3 = TreeNode("l1_l2_l3") 90 | l1_l2_r3 = TreeNode("l1_l2_r3") 91 | l1_r2_l3 = TreeNode("l1_r2_l3") 92 | l1_r2_r3 = TreeNode("l1_r2_r3") 93 | r1_l2_l3 = TreeNode("r1_l2_l3") 94 | r1_l2_r3 = TreeNode("r1_l2_r3") 95 | r1_r2_l3 = TreeNode("r1_r2_l3") 96 | r1_r2_r3 = TreeNode("r1_r2_r3") 97 | 98 | root.left, root.right = l1, r1 99 | l1.left, l1.right = l1_l2, l1_r2 100 | r1.left, r1.right = r1_l2, r1_r2 101 | l1_l2.left, l1_l2.right = l1_l2_l3, l1_l2_r3 102 | l1_r2.left, l1_r2.right = l1_r2_l3, l1_r2_r3 103 | r1_l2.left, r1_l2.right = r1_l2_l3, r1_l2_r3 104 | r1_r2.left, r1_r2.right = r1_r2_l3, r1_r2_r3 105 | 106 | print(list(pre_order(root))) 107 | print(list(in_order(root))) 108 | print(list(post_order(root))) 109 | print(list(layer_order(root))) 110 | print(level_order(root)) 111 | print(get_level(root)) 112 | -------------------------------------------------------------------------------- /15.recursion_tree/cell_division.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 1个细胞的生命周期是3小时,1小时分裂一次。求n小时后,容器内有多少细胞?时间复杂度是多少? 6 | """ 7 | 8 | 9 | def cell_division(n: int): 10 | if n <= 0: return 1 11 | if n == 1: return 2 12 | if n == 2: return 4 13 | if n == 3: return 7 14 | return 2 * cell_division(n - 1) - cell_division(n - 4) 15 | 16 | 17 | for i in range(10): 18 | print("f(%s)=%s" % (i, cell_division(i))) 19 | -------------------------------------------------------------------------------- /15.recursion_tree/permutation_str.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 编程列出一个任意长度字符串的全字符排序情况,原始字符串中没有重复字符 6 | 例如: 7 | 原始字符串是"abc": 8 | 打印所有的排列permutation情况: 9 | "abc" "acb" "bac" "bca" "cab" "cba" 10 | """ 11 | 12 | 13 | def permutation(chars, k): 14 | """ 15 | :param chars: 字符串序列 16 | :param k: 未处理的字符串的起始位置 17 | :return: 18 | """ 19 | if k == len(chars) - 1: 20 | for i in range(len(chars)): 21 | print(chars[i], end="") 22 | print(end=",") 23 | for i in range(k, len(chars)): 24 | chars[k], chars[i] = chars[i], chars[k] 25 | permutation(chars, k + 1) 26 | chars[k], chars[i] = chars[i], chars[k] 27 | 28 | 29 | permutation(list("abc"), 0) 30 | -------------------------------------------------------------------------------- /16.heap/TopK.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from typing import Optional 3 | 4 | __author__ = 'xiaoxiaoming' 5 | 6 | from Heap import Heap 7 | 8 | 9 | class TopK: 10 | def __init__(self, arr: Optional[list] = None, k: int = 10, sort_key=lambda x: x): 11 | self.k = k 12 | self.sort_key = sort_key 13 | self.min_heap = Heap(type="min", sort_key=sort_key) 14 | if arr: 15 | for e in arr: 16 | self.insert(e) 17 | 18 | def insert(self, data): 19 | if self.min_heap.index == self.k: 20 | if self.sort_key(data) > self.sort_key(self.min_heap.get_top()): 21 | self.min_heap.update_top(data) 22 | else: 23 | self.min_heap.insert(data) 24 | 25 | def __repr__(self): 26 | return str(self.min_heap.get_all()) 27 | 28 | 29 | a = [0, 6, 3, 4, 0, 9, 2, 7, 5, -2, 8, 1, 6, 10] 30 | top3 = TopK(arr=a, k=3) 31 | print(top3) 32 | top3.insert(34) 33 | print(top3) 34 | -------------------------------------------------------------------------------- /16.heap/__pycache__/Heap.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/16.heap/__pycache__/Heap.cpython-37.pyc -------------------------------------------------------------------------------- /16.heap/heap_sort.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from Heap import Heap 5 | 6 | 7 | a = [0, 6, 3, 4, 0, 9, 2, 7, 5, -2, 8, 1, 6, 10] 8 | max_heap = Heap(a) 9 | max_heap.sort() 10 | print(a) 11 | -------------------------------------------------------------------------------- /16.heap/median_num.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import math 5 | 6 | from Heap import Heap 7 | 8 | 9 | class PercentileNumber: 10 | def __init__(self, percentile=0.5): 11 | self.min_heap = Heap(type="min") 12 | self.max_heap = Heap(type="max") 13 | self.count = 0 14 | self.percentile = percentile 15 | 16 | def insert(self, data): 17 | self.count += 1 18 | if self.count == 1: 19 | self.max_heap.insert(data) 20 | return 21 | max_count = math.ceil(self.count * self.percentile) 22 | if data <= self.max_heap.get_top(): 23 | self.max_heap.insert(data) 24 | else: 25 | self.min_heap.insert(data) 26 | if max_count > len(self.max_heap): 27 | self.max_heap.insert(self.min_heap.remove_top()) 28 | elif max_count < len(self.max_heap): 29 | self.min_heap.insert(self.max_heap.remove_top()) 30 | 31 | def get_percentile_number(self): 32 | return self.max_heap.get_top() 33 | 34 | 35 | number = PercentileNumber(percentile=0.5) 36 | for i in range(1, 101): 37 | number.insert(i) 38 | print("%s:%s" % (i, number.get_percentile_number()), end=",") 39 | -------------------------------------------------------------------------------- /16.heap/merge_small_file.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import os 5 | from Heap import Heap 6 | 7 | fs = [] 8 | min_heap = Heap(type="min", sort_key=lambda x: int(x[0])) 9 | out = open("out.log", "w") 10 | for i, filename in enumerate(os.listdir("../logs")): 11 | fo = open(os.path.join("../logs", filename)) 12 | fs.append(fo) 13 | min_heap.insert((fo.readline().rstrip(), i)) 14 | 15 | while True: 16 | data, i = min_heap.get_top() 17 | out.write(data) 18 | out.write("\n") 19 | line = fs[i].readline().rstrip() 20 | if line: 21 | min_heap.update_top((line, i)) 22 | else: 23 | min_heap.remove_top() 24 | fs[i].close() 25 | if min_heap.index == -1: break 26 | 27 | out.close() 28 | -------------------------------------------------------------------------------- /19.string_match/bf_rk.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def bf(main, pattern) -> int: 6 | """bf暴搜 7 | :param main: 主串 8 | :param pattern: 模式串 9 | :return: 10 | """ 11 | n = len(main) 12 | m = len(pattern) 13 | 14 | if n <= m: 15 | return 0 if pattern == main else -1 16 | 17 | for i in range(n - m + 1): 18 | for j in range(m): 19 | if main[i + j] != pattern[j]: break 20 | if j == m - 1: return i 21 | return -1 22 | 23 | 24 | def simple_hash(s, start, end): 25 | ret = 0 26 | for i in range(start, end + 1): 27 | ret += ord(s[i]) 28 | return ret 29 | 30 | 31 | def rk(main, pattern): 32 | """rk搜索算法 33 | :param main: 主串 34 | :param pattern: 模式串 35 | :return: 36 | """ 37 | n = len(main) 38 | m = len(pattern) 39 | 40 | if n <= m: 41 | return 0 if pattern == main else -1 42 | 43 | # 子串哈希值表 44 | h = [0] * (n - m + 1) 45 | h[0] = simple_hash(main, 0, m - 1) 46 | for i in range(1, n - m + 1): 47 | h[i] = h[i - 1] - ord(main[i - 1]) + ord(main[i + m - 1]) 48 | # 模式串哈希值 49 | hash_p = simple_hash(pattern, 0, m - 1) 50 | 51 | for i, h in enumerate(h): 52 | # 可能存在哈希冲突 53 | if h == hash_p: 54 | if pattern == main[i:i + m]: 55 | return i 56 | return -1 57 | 58 | 59 | if __name__ == '__main__': 60 | m_str = 'thequickbrownfoxjumpsoverthelazydog' 61 | p_str = 'jump' 62 | print('[bf] result:', bf(m_str, p_str)) 63 | print('[rk] result:', rk(m_str, p_str)) 64 | -------------------------------------------------------------------------------- /19.string_match/bm.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | from typing import List 4 | 5 | 6 | def bm(main: str, pattern: str) -> int: 7 | n, m = len(main), len(pattern) 8 | 9 | if n <= m: 10 | return 0 if main == pattern else -1 11 | 12 | # bc为坏字符位置表 13 | bc = generate_bc(pattern) 14 | # suffix为好后缀匹配的{u*}位置表,prefix为前缀匹配表 15 | suffix, prefix = generate_gs(pattern) 16 | 17 | i = 0 # i表示在主串中的角标 18 | while i <= n - m: 19 | j = m - 1 # j表示在模式串中的角标 20 | while j >= 0 and main[i + j] == pattern[j]: 21 | j -= 1 22 | # j此时表示坏字符首次出现的位置 23 | if j == m - 1: # 坏字符出现在模式串尾部,使用坏字符规则 24 | i += j - bc[ord(main[i + j])] 25 | elif j == -1: # 已经匹配成功 26 | return i 27 | else: # 尾部是好后缀,使用好后缀规则 28 | k = m - 1 - j # 好后缀的长度 29 | if suffix[k] != -1: # 整个好后缀在pattern剩余字符中仍有出现 30 | i += j - suffix[k] + 1 31 | else: 32 | r = k 33 | while r > 0 and not prefix[r]: 34 | r -= 1 35 | i += m - r 36 | return -1 37 | 38 | 39 | def generate_bc(pattern) -> List[int]: 40 | """生成坏字符位置表""" 41 | bc = [-1] * 256 42 | for i, c in enumerate(pattern): 43 | bc[ord(c)] = i 44 | return bc 45 | 46 | 47 | def generate_gs(pattern) -> (List[int], List[bool]): 48 | m = len(pattern) 49 | suffix = [-1] * m 50 | prefix = [False] * m 51 | for i in range(m - 1): 52 | k = 1 # pattern[:i+1]和pattern的公共后缀长度 53 | j = i 54 | while j >= 0 and pattern[j] == pattern[m - k]: 55 | suffix[k] = j 56 | k += 1 57 | j -= 1 58 | if j == -1: prefix[k - 1] = True 59 | return suffix, prefix 60 | 61 | 62 | if __name__ == '__main__': 63 | print('--- search ---') 64 | m_str = 'dfasdeeeetewtweyyyhtruuueyytewtweyyhtrhrth' 65 | p_str = 'ruuueyy' 66 | print('[Built-in Functions] result:', m_str.find(p_str)) 67 | print('[bm] result:', bm(m_str, p_str)) 68 | 69 | -------------------------------------------------------------------------------- /19.string_match/kmp.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | """ 5 | 操作流程: 6 | - 假设现在主串 M 匹配到 i 位置,模式串 P 匹配到 j 位置 7 | - 如果 j = -1,或者当前字符匹配成功(即 M[i] == P[j] ),都令 i++,j++,继续匹配下一个字符; 8 | - 如果 j != -1,且当前字符匹配失败(即 M[i] != P[j] ),则令 i 不变,j = next[j]。 9 | 匹配失败时,模式串 P相对于主串 M 向右移动了 j - next [j] 位 10 | - 换言之,将模式串 P 失配位置的 next 数组的值对应的模式串 P 的索引位置移动到失配处 11 | """ 12 | 13 | 14 | def kmp(main: str, pattern: str): 15 | """kmp字符串匹配""" 16 | n, m = len(main), len(pattern) 17 | 18 | if m == 0: 19 | return 0 20 | if n <= m: 21 | return 0 if main == pattern else -1 22 | 23 | # 求解next数组 24 | next = get_next(pattern) 25 | 26 | i, j = 0, 0 27 | while i < n and j < m: 28 | if j == -1 or main[i] == pattern[j]: 29 | i += 1 30 | j += 1 31 | else: # j!=-1 and main[i]!=pattern[j] 32 | j = next[j] 33 | if j == m: 34 | return i - j 35 | else: 36 | return -1 37 | 38 | 39 | def get_next(pattern): 40 | """next数组生成""" 41 | m = len(pattern) 42 | next = [-1] * m 43 | i, j = 0, -1 44 | while i < m - 1: 45 | if j == -1 or pattern[i] == pattern[j]: 46 | i += 1 47 | j += 1 48 | next[i] = j 49 | else: 50 | j = next[j] 51 | return next 52 | 53 | 54 | # def get_maxL(pattern): 55 | # m = len(pattern) 56 | # maxL = 0 57 | # max_l_arr = [0] * m 58 | # for i in range(1, m): 59 | # if pattern[maxL] != pattern[i]: 60 | # maxL = 0 61 | # if pattern[maxL] == pattern[i]: 62 | # maxL += 1 63 | # max_l_arr[i] = maxL 64 | # return max_l_arr 65 | 66 | 67 | def get_next_arr(pattern): 68 | m = len(pattern) 69 | maxL = 0 70 | next = [0] * m 71 | next[0] = -1 72 | for i in range(1, m - 1): 73 | if pattern[maxL] != pattern[i]: 74 | maxL = 0 75 | if pattern[maxL] == pattern[i]: 76 | maxL += 1 77 | next[i + 1] = maxL 78 | return next 79 | 80 | 81 | if __name__ == '__main__': 82 | m_str = "aabbbbaaabbababbabbbabaaabb" 83 | p_str = "abbabbbabaa" 84 | 85 | print('--- search ---') 86 | print('[Built-in Functions] result:', m_str.find(p_str)) 87 | print('[kmp] result:', kmp(m_str, p_str)) 88 | 89 | print(get_next("abaabcac")) 90 | print(get_next_arr("abaabcac")) 91 | print(get_next("ababacd")) 92 | print(get_next_arr("ababacd")) 93 | print(get_next("abbabbbabaa")) 94 | print(get_next_arr("abbabbbabaa")) 95 | -------------------------------------------------------------------------------- /20.trie/trie_base.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | class TrieNode: 5 | def __init__(self, data: str): 6 | self.data = data 7 | self.children = [None] * 26 8 | self.is_ending_char = False 9 | 10 | 11 | class Trie: 12 | def __init__(self): 13 | self.root = TrieNode("/") 14 | 15 | def insert(self, text: str) -> None: 16 | node = self.root 17 | for index, char in map(lambda x: (ord(x) - ord("a"), x), text): 18 | if node.children[index] is None: 19 | node.children[index] = TrieNode(char) 20 | node = node.children[index] 21 | node.is_ending_char = True 22 | 23 | def find(self, pattern: str) -> bool: 24 | p = self.root 25 | for index in map(lambda x: ord(x) - ord("a"), pattern): 26 | if p.children[index] is None: return False 27 | p = p.children[index] 28 | return p.is_ending_char 29 | 30 | 31 | if __name__ == "__main__": 32 | 33 | strs = ["how", "hi", "her", "hello", "so", "see"] 34 | trie = Trie() 35 | for s in strs: 36 | trie.insert(s) 37 | 38 | for s in strs: 39 | print(trie.find(s)) 40 | 41 | print(trie.find("swift")) 42 | -------------------------------------------------------------------------------- /21.ac_automata/ac_automata.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | from typing import List 3 | 4 | 5 | class ACNode: 6 | def __init__(self, data: str): 7 | self.data = data 8 | self.children = [None] * 26 # 字符集只包含 a~z 这 26 个字符 9 | self.is_ending_char = False # 结尾字符为 true 10 | self.length = -1 # 当 isEndingChar=true 时,记录模式串长度 11 | self.fail = None # 失败指针 12 | 13 | 14 | class ACAutomata: 15 | def __init__(self): 16 | self.root = ACNode("/") 17 | 18 | def insert(self, text: str) -> None: 19 | node = self.root 20 | for index, char in map(lambda x: (ord(x) - ord("a"), x), text): 21 | if node.children[index] is None: 22 | node.children[index] = ACNode(char) 23 | node = node.children[index] 24 | node.is_ending_char = True 25 | node.length = len(text) 26 | 27 | def insert_list(self, patterns: List[str]) -> None: 28 | for pattern in patterns: 29 | self.insert(pattern) 30 | self.build_failure_pointer() 31 | 32 | def build_failure_pointer(self): 33 | queue = deque() 34 | queue.append(self.root) 35 | while queue: 36 | p: ACNode = queue.popleft() 37 | for pc in p.children: 38 | if pc is None: 39 | continue 40 | if p == self.root: 41 | pc.fail = self.root 42 | else: 43 | q = p.fail 44 | while q: 45 | qc = q.children[ord(pc.data) - ord("a")] 46 | if qc: 47 | pc.fail = qc 48 | break 49 | q = q.fail 50 | if q is None: 51 | pc.fail = self.root 52 | queue.append(pc) 53 | 54 | def match(self, text: str) -> list: 55 | """返回该字符串所有匹配的起始角标和字符串长度""" 56 | result = [] 57 | p = self.root 58 | for i, char in enumerate(text): 59 | idx = ord(char) - ord("a") 60 | while p.children[idx] is None and p != self.root: 61 | p = p.fail 62 | p = p.children[idx] 63 | if p is None: p = self.root 64 | tmp = p 65 | while tmp != self.root: 66 | if tmp.is_ending_char: 67 | # print(f"匹配起始下标{i - tmp.length + 1},长度{tmp.length}") 68 | result.append((i - tmp.length + 1, tmp.length)) 69 | tmp = tmp.fail 70 | return result 71 | 72 | def sensitive_word_filtered(self, text: str) -> str: 73 | filter_range_list = self.match(text) 74 | str_list = list(text) 75 | for start, length in filter_range_list: 76 | for i in range(start, start + length): 77 | str_list[i] = "*" 78 | return "".join(str_list) 79 | 80 | if __name__ == "__main__": 81 | patterns = ["at", "art", "oars", "soar"] 82 | ac = ACAutomata() 83 | ac.insert_list(patterns) 84 | 85 | ac.match("soarsoarts") 86 | -------------------------------------------------------------------------------- /23.divide/merge_sort_counting.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | inversion_num = 0 5 | 6 | 7 | def merge_sort(nums, p, r): 8 | if p >= r: 9 | return 10 | mid = (p + r) >> 1 11 | merge_sort(nums, p, mid) 12 | merge_sort(nums, mid + 1, r) 13 | merge(nums, p, mid, r) 14 | 15 | 16 | def merge_sort_counting(nums): 17 | global inversion_num 18 | inversion_num = 0 19 | merge_sort(nums, 0, len(nums) - 1) 20 | 21 | 22 | def merge(arr, p, q, r): 23 | global inversion_num 24 | i, j, k = p, q + 1, 0 # 初始化变量 i, j, k 25 | tmp = [0] * (r - p + 1) # 申请一个大小跟arr[p:r+1]一样的临时数组 26 | while i <= q and j <= r: 27 | if arr[i] <= arr[j]: 28 | tmp[k] = arr[i] 29 | i += 1 30 | else: 31 | inversion_num += q - i + 1 32 | tmp[k] = arr[j] 33 | j += 1 34 | k += 1 35 | # 判断哪个子数组中有剩余的数据 36 | start, end = i, q 37 | if j <= r: start, end = j, r 38 | # 将剩余的数据拷贝到临时数组tmp 39 | while start <= end: 40 | tmp[k] = arr[start] 41 | k += 1 42 | start += 1 43 | # 将tmp中的数组拷贝回 arr[p:r+1] 44 | arr[p: r + 1] = tmp 45 | 46 | 47 | if __name__ == '__main__': 48 | nums = [5, 0, 3, 1, 3, 6, 8, 7] 49 | merge_sort_counting(nums) 50 | print(f'nums : {nums}') 51 | print(f'sorted: {nums}') 52 | print(f'inversion number: {inversion_num}') 53 | 54 | nums = [5, 0, 4, 2, 3, 1, 3, 3, 3, 6, 8, 7] 55 | merge_sort_counting(nums) 56 | print(f'nums : {nums}') 57 | print(f'sorted: {nums}') 58 | print(f'inversion number: {inversion_num}') 59 | -------------------------------------------------------------------------------- /23.divide/min_distance_point.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys, math 5 | from typing import Tuple 6 | 7 | 8 | def get_distance(p1: Tuple, p2: Tuple): 9 | distance = math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) 10 | # print(p1, p2, distance) 11 | return distance 12 | 13 | 14 | def min_distance_point(nums, p, r) -> list: 15 | if r - p < 2: return nums[p:r + 1] 16 | mid = (p + r) >> 1 17 | pots = min_distance_point(nums, p, mid) + min_distance_point(nums, mid + 1, r) 18 | n = len(pots) 19 | min_distance = sys.maxsize 20 | pot1, pot2 = None, None 21 | for i in range(n - 1): 22 | for j in range(i + 1, n): 23 | distance = get_distance(pots[i], pots[j]) 24 | if distance < min_distance: 25 | min_distance = distance 26 | pot1, pot2 = pots[i], pots[j] 27 | return [pot1, pot2] 28 | 29 | 30 | nums = [(5, 0), (4, 2), (3, 2), (3, 1), (3, 4), (3, 6), (8, 7), (2, 3), (1, 1)] 31 | pot = min_distance_point(nums, 0, len(nums) - 1) 32 | p1, p2 = pot 33 | print(pot, get_distance(p1, p2)) 34 | -------------------------------------------------------------------------------- /24.back_track/01_bag.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | max_w = 0 # 存储背包中物品总重量的最大值 5 | # 背包选取的物品列表 6 | picks = [] 7 | picks_with_max_value = [] 8 | 9 | 10 | def bag(i: int, cw: int, items: list, w: int): 11 | """ 12 | 假设背包可承受重量 100,物品重量存储在数组 a 中,那可以这样调用函数: 13 | bag(0, 0, a, 100) 14 | :param i: 当前物品的索引 15 | :param cw: 当前已经装进去的物品的重量和 16 | :param items: 每个物品的重量 17 | :param w: 背包容量 18 | :return: 19 | """ 20 | global max_w 21 | print(i, picks, cw) 22 | if cw == w or i == len(items): # cw==w 表示装满了 ;i==n 表示已经考察完所有的物品 23 | if cw > max_w: 24 | global picks_with_max_value 25 | max_w = cw 26 | picks_with_max_value = [x for x in picks if x != 0] 27 | print("满足:", i, picks, cw) 28 | return 29 | 30 | # 不选第i个物品 31 | picks[i] = 0 32 | bag(i + 1, cw, items, w) 33 | # 选第i个物品 34 | ncw = cw + items[i] 35 | if ncw <= w: # 已经超过可以背包承受的重量的时候,就不要再装了 36 | picks[i] = items[i] 37 | bag(i + 1, ncw, items, w) 38 | 39 | 40 | if __name__ == '__main__': 41 | items_info = [3, 5, 2, 4, 1, 2, 4, 9] 42 | picks = [0] * len(items_info) 43 | w = 8 44 | bag(0, 0, items_info, w) 45 | print(picks_with_max_value, max_w) 46 | -------------------------------------------------------------------------------- /24.back_track/01_bag_adv.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | # 背包选取的物品列表 6 | picks = [] 7 | picks_with_max_value = [] 8 | 9 | 10 | def bag(i: int, cw: int, items_info: list, w: int): 11 | """ 12 | :param i: 当前物品的索引 13 | :param cw: 背包当前重量 14 | :param items_info: 物品的重量和价值信息 15 | :param w: 背包容量 16 | :return: 17 | """ 18 | n = len(items_info) 19 | # 考察完所有物品,或中途已经装满 20 | if cw == w or i == n: 21 | global picks_with_max_value 22 | if get_value(items_info, picks) > get_value(items_info, picks_with_max_value): 23 | picks_with_max_value = picks.copy() 24 | return 25 | 26 | # 不选第i个物品 27 | picks[i] = 0 28 | bag(i + 1, cw, items_info, w) 29 | # 选第i个物品 30 | ncw = cw + items_info[i][0] 31 | if ncw <= w: # 已经超过可以背包承受的重量的时候,就不要再装了 32 | picks[i] = 1 33 | bag(i + 1, ncw, items_info, w) 34 | 35 | 36 | def get_value(items_info: list, items_picks: list): 37 | n = len(items_picks) 38 | if n == 0: return 0 39 | arr = [items_info[i][1] for i in range(n) if items_picks[i] == 1] 40 | return sum(arr) 41 | 42 | 43 | if __name__ == '__main__': 44 | # [(weight, value), ...] 45 | items_info = [(3, 5), (2, 2), (1, 4), (1, 2), (4, 10)] 46 | w = 8 47 | picks = [0] * len(items_info) 48 | bag(0, 0, items_info, w) 49 | max_value_select_list = [items_info[i] for i in range(len(items_info)) if picks_with_max_value[i] == 1] 50 | print(max_value_select_list) 51 | -------------------------------------------------------------------------------- /24.back_track/eight_queens.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | result = [0] * 8 # 角标代表皇后所在的行数,值存储皇后所在的列 5 | n = 0 # 第n个满足条件的情况 6 | 7 | 8 | def print_eight_queen(result): 9 | print(f"----------{str(n).zfill(2)}----------") 10 | for column in result: 11 | print(f"{'* ' * column}Q {'* ' * (8 - column - 1)}") 12 | 13 | 14 | def cal8queen(row: int = 0): 15 | global n 16 | if row == 8: 17 | n += 1 18 | print_eight_queen(result) 19 | for column in range(8): 20 | # 只有在第row行column列放置不与之前已经放置的冲突时才进行放置 21 | if is_ok(row, column): 22 | result[row] = column 23 | cal8queen(row + 1) 24 | 25 | 26 | def is_ok(row, column): 27 | """ 28 | 校验在第row行将皇后放置在第column列是否满足条件 29 | 通过校验的条件是第row行前面所有行,都没有与当前列相同的列数,也不在当前列的对角线上 30 | """ 31 | leftup, rightup = column - 1, column + 1 32 | for i in range(row - 1, -1, -1): 33 | if column == result[i] or leftup == result[i] or rightup == result[i]: 34 | return False 35 | leftup -= 1 36 | rightup += 1 37 | return True 38 | 39 | 40 | cal8queen(0) 41 | -------------------------------------------------------------------------------- /24.back_track/permutations.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | from typing import List 5 | 6 | permutations_list = [] # 全局变量,用于记录每个输出 7 | 8 | 9 | def permutations(nums: List, n: int, pick_count: int): 10 | """ 11 | 从nums选取n个数的全排列,pick_count表示已经选取的个数 12 | 回溯法,用一个栈记录当前路径信息 13 | 当满足n==0时,说明栈中的数已足够,输出并终止遍历 14 | """ 15 | if n == 0: 16 | print(permutations_list) 17 | else: 18 | for i in range(len(nums) - pick_count): 19 | permutations_list[pick_count] = nums[i] 20 | nums[i], nums[len(nums) - pick_count - 1] = nums[len(nums) - pick_count - 1], nums[i] 21 | permutations(nums, n - 1, pick_count + 1) 22 | nums[i], nums[len(nums) - pick_count - 1] = nums[len(nums) - pick_count - 1], nums[i] 23 | 24 | 25 | if __name__ == '__main__': 26 | nums = [1, 2, 3, 4] 27 | n = 3 28 | print(f'list={nums},pick num={n}') 29 | permutations_list = [0] * n 30 | permutations(nums, n, 0) 31 | -------------------------------------------------------------------------------- /24.back_track/regex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | class Pattern: 5 | def __init__(self, regex: str): 6 | self.regex = regex # 正则表达式 7 | self.matched = False 8 | 9 | def rmatch(self, r_idx: int, m_idx: int, main: str): 10 | if self.matched: return # 如果已经匹配了,就不要继续递归了 11 | if r_idx == len(self.regex): # 正则表达式到结尾了 12 | if m_idx == len(main): self.matched = True # 文本串也到结尾了 13 | return 14 | if self.regex[r_idx] == '*': # *匹配1个或多个任意字符 15 | for i in range(m_idx, len(main)): 16 | self.rmatch(r_idx + 1, i + 1, main) 17 | elif self.regex[r_idx] == '?': # ? 匹配0个或者1个字符 18 | self.rmatch(r_idx + 1, m_idx, main) 19 | self.rmatch(r_idx + 1, m_idx + 1, main) 20 | elif m_idx < len(main) and self.regex[r_idx] == main[m_idx]: # 非特殊字符需要精确匹配 21 | self.rmatch(r_idx + 1, m_idx + 1, main) 22 | 23 | def match(self, main): 24 | self.matched = False 25 | self.rmatch(0, 0, main) 26 | return self.matched 27 | 28 | 29 | 30 | if __name__ == '__main__': 31 | regex = 'ab*eee?d' 32 | main = 'abcdsadfkjlekjoiwjiojieeecd' 33 | pattern = Pattern(regex) 34 | match = pattern.match(main) 35 | print(match) 36 | -------------------------------------------------------------------------------- /25.dynamic_programming/01_bag.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from typing import List, Tuple 5 | 6 | 7 | def knapsack2(items_info: list, capacity: int) -> int: 8 | """ 9 | 固定容量的背包,计算能装进背包的物品组合的最大重量 10 | :param items_info: 每个物品的重量 11 | :param capacity: 背包容量 12 | :return: 最大装载重量 13 | """ 14 | n = len(items_info) 15 | states = [False] * (capacity + 1) # 总重量所有的可能是0~capacity,共capacity+1种情况 16 | states[0] = True # 第0个物品不放入背包,此时背包重量为0 17 | # 第0个物品放入背包 18 | if items_info[0] <= capacity: 19 | states[items_info[0]] = True 20 | for i in range(1, n): 21 | wi = items_info[i] # 背包中第i个物品的重量 22 | # 重量最大值为capacity,需确保重量j在放入wi后,总重量依然小于等于capacity 23 | for j in range(capacity - wi, -1, -1): 24 | if states[j]: states[j + wi] = True 25 | for i in range(capacity, -1, -1): 26 | if states[i]: return i 27 | return 0 28 | 29 | 30 | def knapsack3(weight: list, value: list, capacity: int): 31 | """ 32 | 最大承重限制下,计算能装进背包的物品组合的最大价值 33 | :param weight:每个物品的重量 34 | :param value:每个物品的价值 35 | :param capacity:背包最大承重 36 | :return:最大承重限制下的最大价值 37 | """ 38 | n = len(weight) 39 | states = [-1] * (capacity + 1) # 总重量所有的可能是0~capacity,共capacity+1种情况 40 | states[0] = 0 # 第0个物品不放入背包,此时背包价值为0 41 | # 第0个物品放入背包 42 | if weight[0] <= capacity: 43 | states[weight[0]] = value[0] 44 | for i in range(1, n): 45 | wi = weight[i] # 背包中第i个物品的重量 46 | # 重量最大值为capacity,需确保重量j在放入wi后,总重量依然小于等于capacity 47 | for j in range(capacity - wi, -1, -1): 48 | if states[j] != -1: 49 | v = states[j] + value[i] 50 | if v > states[j + wi]: states[j + wi] = v 51 | # 返回最大价值 52 | return max(states) 53 | 54 | 55 | def knapsack3_simple(items_info: List[Tuple[int, int]], capacity: int) -> int: 56 | prev = [0] * (capacity + 1) 57 | for w, v in items_info: 58 | prev = [c >= w and max(prev[c], prev[c - w] + v) for c in range(capacity + 1)] 59 | return prev[-1] 60 | 61 | 62 | if __name__ == '__main__': 63 | items_info = [2, 2, 4, 6, 3] 64 | capacity = 9 65 | print(knapsack2(items_info, capacity)) 66 | 67 | capacity = 8 68 | weight = [3, 2, 1, 1, 4] 69 | value = [5, 2, 4, 2, 10] 70 | print(knapsack3(weight, value, capacity)) 71 | 72 | items_info = [(3, 5), (2, 2), (1, 4), (1, 2), (4, 10)] 73 | print(knapsack3_simple(items_info, capacity)) 74 | -------------------------------------------------------------------------------- /25.dynamic_programming/__pycache__/min_dist.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/25.dynamic_programming/__pycache__/min_dist.cpython-37.pyc -------------------------------------------------------------------------------- /25.dynamic_programming/coins_problem.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys 5 | from typing import List 6 | 7 | 8 | def coins_dp(values: List[int], w: int) -> int: 9 | # memo[i]表示w为i的时候,最少需要的硬币数 10 | memo = [0] * (w + 1) 11 | # 初始化支付0元需要0个硬币 12 | memo[0] = 0 13 | # 可选硬币列表从小到大排序 14 | values.sort() 15 | for i in range(1, w + 1): 16 | min_num = 99999 # 假设最大金额为100000 17 | # 假设values的值为n1,n2,n3,... 18 | # 故memo[i]=min(memo[i-n1], memo[i-n2], ...) + 1 19 | for n in values: 20 | if i - n < 0: break 21 | if min_num > memo[i - n]: 22 | min_num = memo[i - n] 23 | memo[i] = min_num + 1 24 | return memo[-1] 25 | 26 | 27 | def coins_backtracking(values: List[int], w: int): 28 | global min_num, min_coins_list 29 | min_num = sys.maxsize 30 | memo = set() 31 | coins_list = [] 32 | min_coins_list = [] 33 | 34 | def coins_backtracking_in(values: List[int], target: int, cur_value: int, coins_count: int): 35 | if cur_value == target: 36 | global min_num, min_coins_list 37 | if coins_count < min_num: 38 | min_num = coins_count 39 | min_coins_list = coins_list[:coins_count] 40 | return 41 | if (cur_value, coins_count) in memo: return 42 | memo.add((cur_value, coins_count)) 43 | coins_list.append(0) 44 | for n in values: 45 | ncv = cur_value + n 46 | if ncv <= target: 47 | coins_list[coins_count] = n 48 | coins_backtracking_in(values, target, ncv, coins_count + 1) 49 | 50 | coins_backtracking_in(values, w, 0, 0) 51 | return min_coins_list 52 | 53 | 54 | if __name__ == '__main__': 55 | values = [1, 2, 5, 10, 20, 50, 100] 56 | for i in range(1, 501): 57 | print(f"{i}-{coins_dp(values, i)}", end=",") 58 | 59 | print() 60 | target = 22 61 | min_coins_list = coins_backtracking(values, target) 62 | print(min_coins_list, len(min_coins_list)) 63 | -------------------------------------------------------------------------------- /25.dynamic_programming/double11advance.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys 5 | 6 | 7 | def double11advance(items_info: list, w: int): 8 | """ 9 | 动态规划解决双11凑单问题 10 | :param items_info: 每个商品价格 11 | :param w: 满减条件,比如 200 12 | :return: 13 | """ 14 | n = len(items_info) 15 | # 超过 3 倍就没有薅羊毛的价值了 16 | states = [[False] * (3 * w + 1) for i in range(n)] 17 | states[0][0] = True 18 | states[0][items_info[0]] = True 19 | for i in range(1, n): 20 | for j in range(3 * w + 1): 21 | if states[i - 1][j]: 22 | # 不购买第i个商品 23 | states[i][j] = states[i - 1][j] 24 | # 购买第i个商品 25 | nw = j + items_info[i] 26 | if nw <= 3 * w: 27 | states[i][nw] = True 28 | j = w 29 | while j < 3 * w + 1 and not states[n - 1][j]: 30 | j += 1 31 | # j是大于等于 w 的最小值 32 | if j == 3 * w + 1: return # 没有可行解 33 | for i in range(n - 1, 0, -1): 34 | if j - items_info[i] >= 0 and states[i - 1][j - items_info[i]]: 35 | print(items_info[i], end=" ") 36 | j -= items_info[i] 37 | if j != 0: print(items_info[0], end="") 38 | print() 39 | 40 | 41 | def double11advance2(items: list, w: int) -> list: 42 | global mem, min_w, picks, picks_with_min_value 43 | # 存储背包中物品总重量的最小值 44 | min_w = sys.maxsize 45 | # 背包选取的物品列表 46 | picks_with_min_value = [] 47 | picks = [False] * len(items) 48 | mem = set() 49 | 50 | def double11advance_back_track(i: int, cp: int, items: list, p: int): 51 | """ 52 | 回溯算法解决双11凑单问题 53 | :param i: 当前商品的索引 54 | :param cp: 选购的商品总价格 55 | :param items: 每个商品的价格 56 | :param p: 满减条件,比如 200 57 | :return: 58 | """ 59 | global mem, min_w, picks 60 | n = len(items) 61 | # 已经考察完所有的物品 或 选购的商品总价格已经超过之前计算情况,接下来不管选不选都不会产生最优解 62 | if i == n or cp >= min_w: 63 | if p <= cp < min_w: 64 | global picks_with_min_value 65 | min_w = cp 66 | picks_with_min_value = [items[i] for i in range(n) if picks[i]] 67 | return 68 | # 当前状态若已经计算则不计算,未计算则记录当前状态避免下次重复计算 69 | if (i, cp) in mem: return 70 | mem.add((i, cp)) 71 | # 不选第i个商品 72 | picks[i] = False 73 | double11advance_back_track(i + 1, cp, items, p) 74 | # 选第i个商品 75 | picks[i] = True 76 | double11advance_back_track(i + 1, cp + items[i], items, p) 77 | 78 | double11advance_back_track(0, 0, items, w) 79 | return picks_with_min_value 80 | 81 | 82 | if __name__ == '__main__': 83 | items_info = [2, 2, 4, 6, 3] 84 | print(items_info) 85 | capacity = 7 86 | double11advance(items_info, capacity) 87 | 88 | picks_with_min_value = double11advance2(items_info, capacity) 89 | print(picks_with_min_value, sum(picks_with_min_value)) 90 | -------------------------------------------------------------------------------- /25.dynamic_programming/lengthOfLIS.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import bisect 3 | 4 | __author__ = 'xiaoxiaoming' 5 | 6 | from typing import List 7 | 8 | 9 | def lengthOfLIS(nums: List[int]) -> int: 10 | n = len(nums) 11 | if n <= 1: return n 12 | # memo用于避免冗余计算 13 | memo = [[-1] * n for _ in range(n + 1)] 14 | 15 | def lengthOfLIS_in(nums: List[int], prev_idx: int, pos: int) -> int: 16 | if pos == len(nums): return 0 17 | cache = memo[prev_idx + 1][pos] 18 | if cache >= 0: return cache 19 | taken = 0 20 | if prev_idx == -1 or nums[pos] > nums[prev_idx]: 21 | taken = lengthOfLIS_in(nums, pos, pos + 1) + 1 22 | no_taken = lengthOfLIS_in(nums, prev_idx, pos + 1) 23 | result = max(no_taken, taken) 24 | memo[prev_idx + 1][pos] = result 25 | return result 26 | 27 | return lengthOfLIS_in(nums, -1, 0) 28 | 29 | 30 | def longest_increasing_subsequence(nums: List[int]) -> int: 31 | """ 32 | 状态定义:dp[i]的值代表nums前i个数字的最长子序列长度。 33 | 转移方程:设 j∈[0,i),考虑每轮计算新dp[i]时,遍历[0,i)列表区间,做以下判断: 34 | 1.当nums[i]>nums[j]时:nums[i]可以接在 nums[j]之后,此时最长上升子序列长度为dp[j]+1; 35 | 2.当 nums[i]<=nums[j]时:nums[i]无法接在 nums[j]之后,此情况上升子序列不成立,跳过。 36 | dp[i]为情况1所有结果的最大值,若没有条件1的情况,则dp[i]=1 37 | 具体实现时,将dp[i]所有元素置1,含义是每个元素都至少可以单独成为子序列,此时长度都为1。 38 | 最后返回dp列表最大值,即可得到全局最长上升子序列长度。 39 | """ 40 | n = len(nums) 41 | if n <= 1: return n 42 | dp = [1] * n 43 | result = 1 44 | for i in range(1, n): 45 | for j in range(i): 46 | if nums[i] > nums[j]: 47 | dp[i] = max(dp[i], dp[j] + 1) 48 | if dp[i] > result: result = dp[i] 49 | return result 50 | 51 | 52 | def lengthOfLIS_by_binary_search(nums: [int]) -> int: 53 | n = len(nums) 54 | if n <= 1: return n 55 | tails, res = [0] * n, 0 56 | for num in nums: 57 | low, high = 0, res - 1 58 | # 在tails数组中通过二分搜索查找num的插入位置 59 | # 可将该问题视为二分搜索的变体三:查找第一个大于等于num的元素位置,最终low的值即为插入点位置 60 | while low <= high: 61 | mid = (low + high) >> 1 62 | if tails[mid] >= num: 63 | high = mid - 1 64 | else: 65 | low = mid + 1 66 | tails[low] = num 67 | if low == res: res += 1 68 | return res 69 | 70 | 71 | def maxEnvelopes(envelopes: List[List[int]]) -> int: 72 | envelopes.sort(key=lambda a: (a[0], -a[1])) 73 | height = list(map(lambda x: x[1], envelopes)) 74 | return lengthOfLIS_by_binary_search2(height) 75 | 76 | 77 | def lengthOfLIS_by_binary_search2(nums: [int]) -> int: 78 | n = len(nums) 79 | if n <= 1: return n 80 | tails, res = [0] * n, 0 81 | for num in nums: 82 | i = bisect.bisect_left(tails, num, 0, res) 83 | tails[i] = num 84 | if i == res: res += 1 85 | return res 86 | 87 | 88 | if __name__ == '__main__': 89 | nums = [10, 9, 2, 5, 3, 7, 101, 18] 90 | print(lengthOfLIS(nums)) 91 | print(longest_increasing_subsequence(nums)) 92 | print(lengthOfLIS_by_binary_search(nums)) 93 | print(lengthOfLIS_by_binary_search2(nums)) 94 | -------------------------------------------------------------------------------- /25.dynamic_programming/max_envelopes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import bisect 5 | from typing import List 6 | 7 | 8 | """ 9 | 给定一些标记了宽度和高度的信封,宽度和高度以整数对形式 (w, h) 出现。 10 | 当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。 11 | 请计算最多能有多少个信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。 12 | 说明: 13 | 不允许旋转信封。 14 | 15 | 示例: 16 | 输入: envelopes = [[5,4],[6,4],[6,7],[2,3]] 17 | 输出: 3 18 | 解释: 最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。 19 | 20 | 来源:力扣(LeetCode) 21 | 链接:https://leetcode-cn.com/problems/russian-doll-envelopes 22 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 23 | """ 24 | 25 | def maxEnvelopes(envelopes: List[List[int]]) -> int: 26 | envelopes.sort(key=lambda a: (a[0], -a[1])) 27 | height = list(map(lambda x: x[1], envelopes)) 28 | return lengthOfLIS(height) 29 | 30 | 31 | def lengthOfLIS(nums: [int]) -> int: 32 | n = len(nums) 33 | if n <= 1: return n 34 | tails, res = [0] * n, 0 35 | for num in nums: 36 | i = bisect.bisect_left(tails, num, 0, res) 37 | tails[i] = num 38 | if i == res: res += 1 39 | return res 40 | 41 | if __name__ == '__main__': 42 | print(maxEnvelopes([[5,4],[6,4],[6,7],[2,3]])) -------------------------------------------------------------------------------- /25.dynamic_programming/min_dist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import sys 5 | from typing import List 6 | 7 | 8 | def min_dist_DP(matrix: List[List[int]]) -> int: 9 | m, n = len(matrix), len(matrix[0]) 10 | states = [[0] * n for _ in range(m)] 11 | sum = 0 12 | for j in range(n): 13 | sum += matrix[0][j] 14 | states[0][j] = sum 15 | sum = 0 16 | for i in range(n): 17 | sum += matrix[i][0] 18 | states[i][0] = sum 19 | for i in range(1, n): 20 | for j in range(1, n): 21 | states[i][j] = matrix[i][j] + min(states[i][j - 1], states[i - 1][j]) 22 | return states[-1][-1] 23 | 24 | 25 | def min_dist(matrix: List[List[int]]): 26 | m, n = len(matrix), len(matrix[0]) 27 | mem = [[0] * n for _ in range(m)] 28 | 29 | def min_dist_in(i: int, j: int): 30 | if i == j == 0: return matrix[0][0] 31 | if mem[i][j]: return mem[i][j] 32 | if i < 0 or j < 0: return sys.maxsize 33 | curr_min_dist = matrix[i][j] + min(min_dist_in(i, j - 1), min_dist_in(i - 1, j)) 34 | mem[i][j] = curr_min_dist 35 | return curr_min_dist 36 | 37 | return min_dist_in(m - 1, n - 1) 38 | 39 | 40 | if __name__ == "__main__": 41 | weights = [[1, 3, 5, 9], 42 | [2, 1, 3, 4], 43 | [5, 2, 6, 7], 44 | [6, 8, 4, 3]] 45 | print(min_dist_DP(weights)) 46 | print(min_dist(weights)) 47 | -------------------------------------------------------------------------------- /25.dynamic_programming/min_edit_dist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | 5 | def lwst_dp(a: str, b: str) -> int: 6 | """ 7 | 如果:a[i]!=b[j],min_edist(i, j)= 8 | min(min_edist(i-1,j)+1, min_edist(i,j-1)+1, min_edist(i-1,j-1)+1) 9 | 如果:a[i]==b[j],min_edist(i, j)= 10 | min(min_edist(i-1,j)+1, min_edist(i,j-1)+1,min_edist(i-1,j-1)) 11 | """ 12 | n, m = len(a), len(b) 13 | min_edist = [[0] * m for _ in range(n)] 14 | ## 初始化第一个元素 15 | if a[0] != b[0]: 16 | min_edist[0][0] = 1 17 | # 初始化第一行 18 | for j in range(1, m): 19 | if a[0] == b[j]: 20 | min_edist[0][j] = j 21 | else: 22 | min_edist[0][j] = min_edist[0][j - 1] + 1 23 | # 初始化第一列 24 | for i in range(1, n): 25 | if a[i] == b[0]: 26 | min_edist[i][0] = i 27 | else: 28 | min_edist[i][0] = min_edist[i - 1][0] + 1 29 | for i in range(1, n): 30 | for j in range(1, m): 31 | tmp = min_edist[i - 1][j - 1] 32 | if a[i] != b[j]: tmp += 1 33 | min_edist[i][j] = min(min_edist[i - 1][j] + 1, min_edist[i][j - 1] + 1, 34 | tmp) 35 | print(min_edist) 36 | return min_edist[-1][-1] 37 | 38 | 39 | def lcs(a: str, b: str): 40 | """ 41 | 如果:a[i]==b[j],那么:max_lcs(i, j) 就等于: 42 | max(max_lcs(i-1,j-1)+1, max_lcs(i-1, j), max_lcs(i, j-1)); 43 | 如果:a[i]!=b[j],那么:max_lcs(i, j) 就等于: 44 | max(max_lcs(i-1,j-1), max_lcs(i-1, j), max_lcs(i, j-1)); 45 | """ 46 | n, m = len(a), len(b) 47 | # 第0行和第0列作为哨兵元素 48 | max_lcs = [[0] * (m + 1) for _ in range(n + 1)] 49 | for i in range(1, n + 1): 50 | for j in range(1, m + 1): 51 | max_lcs[i][j] = max(max_lcs[i - 1][j], max_lcs[i][j - 1], 52 | max_lcs[i - 1][j - 1] + int(a[i - 1] == b[j - 1])) 53 | return max_lcs[-1][-1] 54 | 55 | 56 | if __name__ == "__main__": 57 | a = "mitcmu" 58 | b = "mtacnu" 59 | print(lwst_dp(a, b)) 60 | print(lcs(a, b)) 61 | 62 | a = "kitten" 63 | b = "sitting" 64 | print(lwst_dp(a, b)) 65 | print(lcs(a, b)) 66 | 67 | a = "flaw" 68 | b = "lawn" 69 | print(lwst_dp(a, b)) 70 | print(lcs(a, b)) -------------------------------------------------------------------------------- /25.dynamic_programming/yh_triangle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: UTF-8 -*- 3 | 4 | from typing import List 5 | 6 | 7 | def yh_triangle(nums: List[List[int]]) -> int: 8 | n = len(nums) # 层数 9 | memo = [0] * n 10 | memo[0] = nums[0][0] 11 | for i in range(1, n): 12 | for j in range(i, -1, -1): 13 | if j == i: 14 | memo[j] = memo[j - 1] + nums[i][j] 15 | elif j == 0: 16 | memo[j] += nums[i][j] 17 | else: 18 | memo[j] = min(memo[j - 1] + nums[i][j], memo[j] + nums[i][j]) 19 | return min(memo) 20 | 21 | 22 | def yh_triangle_bottom_up(nums: List[List[int]]) -> int: 23 | n = len(nums) 24 | memo = nums[-1].copy() 25 | for i in range(n - 1, 0, -1): 26 | for j in range(i): 27 | memo[j] = min(memo[j] + nums[i - 1][j], memo[j + 1] + nums[i - 1][j]) 28 | return memo[0] 29 | 30 | 31 | if __name__ == '__main__': 32 | nums = [[3], [2, 6], [5, 4, 2], [6, 0, 3, 2], [3, 2, 1, 8, 4]] 33 | for num in nums: 34 | print(num) 35 | print(yh_triangle(nums)) 36 | print(yh_triangle_bottom_up(nums)) 37 | -------------------------------------------------------------------------------- /26.topological_sorting/topological_sorting.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | from collections import deque 5 | 6 | 7 | class Graph: 8 | def __init__(self, v: int): 9 | self.v = v # 顶点的个数 10 | self.adj = [deque() for _ in range(v)] # 邻接表 11 | 12 | def add_edge(self, s: int, t: int) -> None: 13 | self.adj[s].append(t) 14 | 15 | def topo_sort_by_kahn(self) -> None: 16 | in_degree = [0] * self.v 17 | for i in range(self.v): 18 | if len(self.adj[i]): 19 | for w in self.adj[i]: 20 | in_degree[w] += 1 21 | queue = deque() 22 | for i in range(self.v): 23 | if in_degree[i] == 0: queue.append(i) 24 | while queue: 25 | i = queue.popleft() 26 | print(f"{i} -> ", end="") 27 | for k in self.adj[i]: 28 | in_degree[k] -= 1 29 | if in_degree[k] == 0: 30 | queue.append(k) 31 | print("\b\b\b\b") 32 | 33 | def topp_sort_by_dfs(self) -> None: 34 | # 先构建逆邻接表,边s->t表示s依赖于t,t先于s 35 | inverse_adjacency = [deque() for _ in range(self.v)] 36 | for i in range(self.v): 37 | if len(self.adj[i]): 38 | for w in self.adj[i]: 39 | inverse_adjacency[w].append(i) 40 | visited = [False] * self.v 41 | 42 | def dfs(vertex: int) -> None: 43 | if len(inverse_adjacency[vertex]): 44 | for w in inverse_adjacency[vertex]: 45 | if not visited[w]: 46 | visited[w] = True 47 | dfs(w) 48 | print(f"{vertex} -> ", end="") 49 | 50 | for i in range(self.v): 51 | if not visited[i]: 52 | visited[i] = True 53 | dfs(i) 54 | print("\b\b\b\b") 55 | 56 | 57 | if __name__ == "__main__": 58 | dag = Graph(4) 59 | dag.add_edge(1, 0) 60 | dag.add_edge(2, 1) 61 | dag.add_edge(1, 3) 62 | dag.topo_sort_by_kahn() 63 | dag.topp_sort_by_dfs() 64 | -------------------------------------------------------------------------------- /27.weighted_graph/dijkstra.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'xiaoxiaoming' 3 | 4 | import heapq 5 | from collections import deque 6 | 7 | 8 | def print_path(predecessor, s, t): 9 | result = deque() 10 | while t != s: 11 | result.appendleft(str(t)) 12 | t = predecessor[t] 13 | result.appendleft(str(s)) 14 | print(" -> ".join(result)) 15 | 16 | 17 | class Graph: 18 | def __init__(self, vertex_count: int): 19 | self.adj = [deque() for _ in range(vertex_count)] 20 | 21 | def add_edge(self, s: int, t: int, w: int): 22 | self.adj[s].append(Edge(s, t, w)) 23 | 24 | def dijkstra(self, s: int, t: int): 25 | v = len(self.adj) 26 | predecessor = [0] * v 27 | vertexes = [Vertex(i) for i in range(v)] 28 | queue = VertexPriorityQueue() 29 | inqueue = [False] * v 30 | vertexes[s].dist = 0 31 | queue.add(vertexes[s]) 32 | inqueue[s] = True 33 | 34 | while not queue.is_empty(): 35 | min_vertex: Vertex = queue.poll() 36 | if min_vertex.id == t: break 37 | for e in self.adj[min_vertex.id]: 38 | next_vertex = vertexes[e.tid] 39 | if min_vertex.dist + e.w < next_vertex.dist: 40 | next_vertex.dist = min_vertex.dist + e.w 41 | predecessor[next_vertex.id] = min_vertex.id 42 | if inqueue[next_vertex.id]: 43 | queue.update(next_vertex) 44 | else: 45 | queue.add(next_vertex) 46 | inqueue[next_vertex.id] = True 47 | print_path(predecessor, s, t) 48 | return vertexes[t].dist 49 | 50 | 51 | class Edge: 52 | def __init__(self, sid: int, tid: int, w: int) -> None: 53 | self.sid = sid 54 | self.tid = tid 55 | self.w = w 56 | 57 | 58 | class Vertex: 59 | def __init__(self, id: int, dist: int = float("inf")) -> None: 60 | self.id = id 61 | self.dist = dist 62 | 63 | def __gt__(self, other) -> bool: 64 | return self.dist > other.dist 65 | 66 | 67 | class VertexPriorityQueue: 68 | def __init__(self) -> None: 69 | self.vertices = [] 70 | 71 | def poll(self) -> Vertex: 72 | return heapq.heappop(self.vertices) 73 | 74 | def add(self, vertex: Vertex) -> None: 75 | heapq.heappush(self.vertices, vertex) 76 | 77 | def update(self, vertex: Vertex) -> None: 78 | for i, v in enumerate(self.vertices): 79 | if vertex.id == v.id: 80 | v.dist = vertex.dist 81 | heapq._siftdown(self.vertices, 0, i) 82 | break 83 | 84 | def is_empty(self) -> bool: 85 | return len(self.vertices) == 0 86 | 87 | 88 | if __name__ == '__main__': 89 | g = Graph(6) 90 | g.add_edge(0, 1, 10) 91 | g.add_edge(0, 4, 15) 92 | g.add_edge(1, 2, 15) 93 | g.add_edge(1, 3, 2) 94 | g.add_edge(2, 5, 5) 95 | g.add_edge(3, 2, 1) 96 | g.add_edge(3, 5, 12) 97 | g.add_edge(4, 5, 10) 98 | print(g.dijkstra(0, 5)) 99 | 100 | g = Graph(4) 101 | g.add_edge(0, 1, 18) 102 | g.add_edge(0, 2, 3) 103 | g.add_edge(2, 1, 1) 104 | g.add_edge(1, 3, 5) 105 | g.add_edge(2, 3, 8) 106 | g.add_edge(0, 3, 15) 107 | print(g.dijkstra(0, 3)) 108 | -------------------------------------------------------------------------------- /28.bitmap/bitmap.py: -------------------------------------------------------------------------------- 1 | class Bitmap: 2 | def __init__(self, nbits: int): 3 | self.nbits = nbits 4 | self.bytes = bytearray((nbits >> 3) + 1) 5 | 6 | def setbit(self, k: int) -> None: 7 | if k > self.nbits or k < 1: return 8 | self.bytes[k >> 3] |= (1 << k % 8) 9 | 10 | def getbit(self, k: int) -> bool: 11 | if k > self.nbits or k < 1: return False 12 | return self.bytes[k >> 3] & (1 << k % 8) != 0 13 | 14 | 15 | if __name__ == "__main__": 16 | bitmap = Bitmap(10) 17 | bitmap.setbit(1) 18 | bitmap.setbit(3) 19 | bitmap.setbit(6) 20 | bitmap.setbit(7) 21 | bitmap.setbit(8) 22 | 23 | for i in range(1, 11): 24 | print(i, bitmap.getbit(i)) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 本文档是[《数据结构与算法之美》](http://gk.link/a/108GK)的学习笔记和个人编写的python实现的相关代码。 2 | 3 | 在线阅读地址:https://datastructure.xiaoxiaoming.xyz/ 4 | 5 | 6 | 7 | 如果本文档对您有用,期待您点击右上角Star :star: 给予关注!谢谢拉! 8 | 9 | 还可以分享给您身边更多的小伙伴!:kissing_heart: 10 | 11 | 12 | 13 | **若你有什么更好的建议,欢迎提交pull或issue进行反馈,每篇文档本身也支持评论,评论后我都可以在issue或原文档页面看到。** 14 | 15 | ------ 16 | 17 | ![1574073361716](docs/imgs/1574073361716.jpg) 18 | 19 | 本文档与原课程的目录会有点差别,本人进行了一些合并和重新编号,新排版的目录为: 20 | 21 | * **入门篇** 22 | * [01.入门篇](docs/01.入门篇.md) 23 | 24 | 25 | 26 | * **基础篇** 27 | * [02.数组](docs/02.数组.md) 28 | * [03.链表](docs/03.链表.md) 29 | * [04.栈](docs/04.栈.md) 30 | * [05.队列](docs/05.队列.md) 31 | * [06.递归](docs/06.递归.md) 32 | * [07.排序](docs/07.排序.md) 33 | * [09.二分查找](docs/09.二分查找.md) 34 | * [10.跳表](docs/10.跳表.md) 35 | * [11.散列表](docs/11.散列表.md) 36 | * [12.哈希算法](docs/12.哈希算法.md) 37 | * [13.二叉树基础](docs/13.二叉树基础.md) 38 | * [14.红黑树](docs/14.红黑树.md) 39 | * [15.递归树](docs/15.递归树.md) 40 | * [16.堆](docs/16.堆.md) 41 | * [17.图的表示](docs/17.图的表示.md) 42 | * [18.深度和广度优先搜索](docs/18.深度和广度优先搜索.md) 43 | * [19.字符串匹配基础](docs/19.字符串匹配基础.md) 44 | * [20.Trie树](docs/20.Trie树.md) 45 | * [21.AC自动机](docs/21.AC自动机.md) 46 | * [22.贪心算法](docs/22.贪心算法.md) 47 | * [23.分治算法](docs/23.分治算法.md) 48 | * [24.回溯算法](docs/24.回溯算法.md) 49 | * [25.动态规划](docs/25.动态规划.md) 50 | 51 | 52 | 53 | * **高级篇** 54 | * [26.拓扑排序](docs/26.拓扑排序.md) 55 | * [27.有权图的应用:最短路径](docs/27.有权图的应用:最短路径.md) 56 | * [28.位图&布隆过滤器](docs/28.位图&布隆过滤器.md) 57 | * [29.B+树](docs/29.B+树.md) 58 | * [30.索引](docs/30.索引.md) 59 | * [31.并行算法](docs/31.并行算法.md) 60 | 61 | 62 | 63 | * **实战篇** 64 | 65 | * [32.Redis用到的数据结构](docs/32.Redis用到的数据结构.md) 66 | * [33.搜索引擎的理论基础](docs/33.搜索引擎的理论基础.md) 67 | * [34.高性能队列Disruptor](docs/34.高性能队列Disruptor.md) 68 | * [35.微服务的鉴权限流接口](docs/35.微服务的鉴权限流接口.md) 69 | * [36.短网址服务系统](docs/36.短网址服务系统.md) 70 | 71 | 72 | 73 | * **结束篇** 74 | * [37.权衡选择数据结构和算法](docs/37.权衡选择数据结构和算法.md) 75 | * [38.leetcode练习题](docs/38.leetcode练习题.md) 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/.nojekyll -------------------------------------------------------------------------------- /docs/28.位图&布隆过滤器.md: -------------------------------------------------------------------------------- 1 | # 位图&布隆过滤器 2 | 3 | ## 位图 4 | 5 | 位图可以看成是一种比较“特殊”的散列表。比如有 1 千万个整数,要查找某个整数是否在这 1 千万个整数中,就可以使用位图。 6 | 7 | 如果整数的范围在 1 到 1 亿之间,申请一个大小为 1 亿、数据类型为布尔类型的数组。将这 1 千万个整数作为数组下标,将对应的数组值设置成 true。比如有整数 5 就设置array[5]=true。查询某个整数 K 是否在这 1 千万个整数中的时候,只需要读取array[K]是否等于 true。 8 | 9 | 不过,很多语言中提供的布尔类型大小是 1 个字节的,实际上,表示 true 和 false 两个值只需要用一个二进制位(bit)。通过位运算用其中的某个位表示某个数字即可: 10 | 11 | ```java 12 | public class BitMap { // Java中char类型占16bit,也即是2个字节 13 | private char[] bytes; 14 | private int nbits; 15 | 16 | public BitMap(int nbits) { 17 | this.nbits = nbits; 18 | this.bytes = new char[nbits/16+1]; 19 | } 20 | 21 | public void set(int k) { 22 | if (k > nbits) return; 23 | int byteIndex = k / 16; 24 | int bitIndex = k % 16; 25 | bytes[byteIndex] |= (1 << bitIndex); 26 | } 27 | 28 | public boolean get(int k) { 29 | if (k > nbits) return false; 30 | int byteIndex = k / 16; 31 | int bitIndex = k % 16; 32 | return (bytes[byteIndex] & (1 << bitIndex)) != 0; 33 | } 34 | } 35 | ``` 36 | 37 | 位图适用于数字所在的范围不是很大的情况,如果数字的范围很大不是 1 到 1 亿而是 1 到 10 亿,那位图的大小消耗的内存空间可能不降反增。**布隆过滤器**(Bloom Filter)就是解决这个问题,对位图的内存消耗的优化。 38 | 39 | ## 布隆过滤器 40 | 41 | **布隆过滤器**(Bloom Filter)是基于位图这种数据结构的一种改进。 42 | 43 | 对于数据的范围1到10亿,布隆过滤器的仍然使用大小为1亿数组,然后使用 K 个哈希函数,对同一个数字进行求哈希值。每个哈希函数都会将数据映射到数组的某个角标,从而得到 K 个不同的哈希值分别记作 $X_1$,$X_2$,$X_3$,…,$X_K$。把这K个数字对应的 BitMap[$X_1$],BitMap[$X_2$],BitMap[$X_3$],…,BitMap[$X_K$] 都设置成 true。 44 | 45 | 意味着布隆过滤器用K个二进制位,来表示一个数据是否不存在。 46 | 47 | 当查询某个数字是否存在的时候,用同样的 K 个哈希函数,对这个数字求哈希值分别得到 $Y_1$,$Y_2$,$Y_3$,…,$Y_K$。再查看这K个哈希值,对应位图中的数值是否都为true。如果都为true则说明这个数字可能存在,如果有其中任意一个不为true,那就说明这个数字必定不存在。 48 | 49 | 如果有其中任意一个不为true,那就说明这个数字必定不存在: 50 | 51 | ![1570506063479](imgs/2/1570506063479.png) 52 | 53 | 如果都为true并不能说明这个数字一定存在: 54 | 55 | ![1570506081739](imgs/2/1570506081739.png) 56 | 57 | 尽管布隆过滤器会存在误判,但这并不影响它发挥大作用。很多场景对误判有一定的容忍度。比如爬虫判重问题,即便一个没有被爬取过的网页被误判为已经被爬取,对于搜索引擎来说也是可以容忍的,毕竟网页太多了搜索引擎也不可能 100% 都爬取到。 58 | 59 | 60 | 61 | # 如何实现网页爬虫中的URL去重功能? 62 | 63 | 爬虫的工作原理是,通过解析已经爬取页面中的网页链接,然后再爬取这些链接对应的网页。 64 | 65 | **同一个网页链接有可能被包含在多个页面中,为了避免重复爬取**,所以需要记录已经爬取的网页链接(也就是 URL)到已爬列表,爬取前判断是否已经爬取过。 66 | 67 | 另外,每爬取一个页面会将解析到的url添加到待爬列表,一个被解析出来的url需要高效的判断是否已经添加到已爬列表被爬取过,还要高效判断是否已经添加到待爬列表中。 68 | 69 | 为了增大已爬和待爬列表内存极限,可以采用分治的思想,用多台机器(比如 20 台内存是 8GB 的机器)来存储10亿以上的网页链接。 70 | 71 | 实现爬虫判重列表可以使用散列表或布隆过滤器来实现。 72 | 73 | ## 散列表vs布隆过滤器 74 | 75 | 内存消耗对比: 76 | 77 | 假设要爬取10亿个网页,一个 URL 的平均长度是 64 字节,那单纯存储这10亿个URL,需要大约60GB的内存空间。 78 | 79 | 散列表必须维持较小的装载因子,用链表法解决冲突问题,还需要存储链表指针。如果将这10亿个URL存储到散列表,需要的内存空间有可能会超过100GB。 80 | 81 | 但如果用布隆过滤器记录已经爬取过的网页链接,即使用10倍大小(100 亿个二进制位)的位图来存储,也只需要大约1.2GB内存即可。 82 | 83 | 84 | 85 | 查询操作耗时对比: 86 | 87 | 如果散列表基于链表的方法解决冲突问题,链表中的结点在内存中是离散存储的,无法一下子加载到CPU缓存中利用CPU高速缓存。这个操作涉及很多内存数据的读取是内存密集型的操作,而且还需要逐个进行字符串匹配。 88 | 89 | 而布隆过滤器用多个哈希函数对同一个网页链接进行处理,CPU 只需要将网页链接从内存中读取一次,进行多次哈希计算,这组操作是 CPU 密集型的操作。 90 | 91 | 所以对于查询操作,布隆过滤器的速度会比散列表快很多。 92 | 93 | ## 布隆过滤器总结 94 | 95 | 布隆过滤器非常适合不需要 100% 准确的、允许存在小概率误判的大规模判重场景。除了爬虫网页去重,还有统计大型网站每日UV都可以使用布隆过滤器,对重复访问的用户,进行去重。 96 | 97 | 布隆过滤器的误判率,主要跟哈希函数的个数、位图的大小有关。往布隆过滤器中不停地加入数据之后,位图中不是 true 的位置就越来越少了,误判率就越来越高了。所以,对于无法事先知道要判重的数据个数的情况,需要支持自动扩容的功能。 98 | 99 | 当布隆过滤器中,数据个数与位图大小的比例超过某个阈值的时候,就可以重新申请一个新的位图。后面来的新数据,会被放置到新的位图中。不过判断某个数据是否存在时需要查看多个位图,执行效率会降低一些。 100 | 101 | 各编程语言对位图、布隆过滤器的实现例子,例如Java中的BitSet,Redis中的BitMap,Google的Guava工具包中的BloomFilter。 102 | 103 | # 思考题 104 | 105 | 假设有1亿个整数,数据范围是从1到10亿,如何快速并且省内存地给这1亿个数据从小到大排序? 106 | 107 | 答: 108 | 109 | 假设不需要统计每个整数的重复次数,可以申请一个大小为10亿的位图,只需大约128MB内存,按照下标顺序输出位图上为true的下标即可完成排序。 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /docs/30.索引.md: -------------------------------------------------------------------------------- 1 | # 索引:快速在海量数据中查找某个数据 2 | 3 | ## 为什么需要索引? 4 | 5 | 在实际的软件开发中,其实它们的本质都可以抽象为“对数据的存储和计算”。对应到数据结构和算法中,那“存储”需要的就是数据结构,“计算”需要的就是算法。 6 | 7 | “如何节省存储空间、如何提高数据增删改查的执行效率”,这样的问题是设计的重点。索引设计得好坏,直接决定了一个系统的性能是否优秀。 8 | 9 | 索引这个概念可以类比书籍的目录,如果没有目录查找某个知识点的时候,就要一页一页翻。通过目录则就可以快速定位相关知识点的页数,查找的速度也会有质的提高。 10 | 11 | ## 索引的需求定义 12 | 13 | 对于系统设计需求,一般可以从**功能性需求**和**非功能性需求**两方面来分析。 14 | 15 | ### 1. 功能性需求 16 | 17 | **数据是格式化数据还是非格式化数据**? 18 | 19 | 结构化数据,比如MySQL 中的数据; 20 | 21 | 非结构化数据,比如搜索引擎中网页。 22 | 23 | 对于非结构化数据,一般需要做预处理,提取出查询关键词,对关键词构建索引。 24 | 25 | **数据是静态数据还是动态数据**? 26 | 27 | 对于静态数据只需要考虑查询效率就可以了,这样索引的构建就相对简单些。 28 | 29 | 但大部分情况下都是对动态数据构建索引,在原始数据更新的同时还需要动态地更新索引。 30 | 31 | 支持动态数据集合的索引,设计起来相对也要更加复杂些。 32 | 33 | **索引存储在内存还是硬盘**? 34 | 35 | 存储在内存的查询速度肯定比存储在磁盘中的高,但因为内存有限,有时就不得不将索引存储在磁盘中。实际上,还可以一部分存储在内存,一部分存储在磁盘,兼顾内存消耗和查询效率。 36 | 37 | **单值查找还是区间查找**? 38 | 39 | 单值查找就是查找关键词等于某个值的数据。 40 | 41 | 区间查找,就是查找关键词处于某个区间值的所有数据。 42 | 43 | **单关键词查找还是多关键词组合查找**? 44 | 45 | 单关键词的查找,索引构建起来相对简单些。 46 | 47 | 对于多关键词查询来说: 48 | 49 | 对于像 MySQL 这种结构化数据的查询需求,可以针对多个关键词的组合,建立索引; 50 | 51 | 对于像搜索引擎这样的非结构数据的查询需求,可以针对单个关键词构建索引,然后通过集合操作,比如求并集、求交集等,计算出多个关键词组合的查询结果。 52 | 53 | ### 2. 非功能性需求 54 | 55 | **不管是存储在内存中还是磁盘中,索引对存储空间的消耗不能过大**。 56 | 57 | 如果存储在内存中,索引对占用存储空间的限制就会非常苛刻。毕竟内存空间非常有限,一个中间件启动后就占用几个 GB 的内存,开发者显然是无法接受的。 58 | 59 | 如果存储在硬盘中,那索引对占用存储空间的限制,稍微会放宽一些。但也不能掉以轻心。因为有时候,索引对存储空间的消耗会超过原始数据。 60 | 61 | **在考虑索引查询效率的同时,还要考虑索引的维护成本**。 62 | 63 | 索引的目的是提高查询效率,但基于动态数据集合构建的索引,还要考虑到,索引的维护成本。 64 | 65 | 对原始数据动态增删改的同时,也需要动态的更新索引。而索引的更新势必会影响到增删改操作的性能。 66 | 67 | ## 构建索引常用的数据结构 68 | 69 | 常用来构建索引的数据结构,有散列表、红黑树、跳表、B+ 树。除此之外,位图、布隆过滤器可以作为辅助索引,有序数组可以用来对静态数据构建索引。 70 | 71 | **散列表**增删改查操作的时间复杂度是 O(1)。一些键值数据库,比如 Redis、Memcache,就是使用散列表来构建索引的。这类索引,一般都构建在内存中。 72 | 73 | **红黑树**作为一种常用的平衡二叉查找树,数据插入、删除、查找的时间复杂度是 O(logn),也非常适合用来构建内存索引。Ext 文件系统中,对磁盘块的索引,用的就是红黑树。 74 | 75 | **B+ 树**比起红黑树来说,更加适合构建存储在磁盘中的索引。B+ 树是一个多叉树,所以,对相同个数的数据构建索引,B+ 树的高度要低于红黑树。当借助索引查询数据的时候,读取 B+ 树索引,需要的磁盘 IO 次数非常更少。所以,大部分关系型数据库的索引,比如 MySQL、Oracle,都是用 B+ 树来实现的。 76 | 77 | **跳表**也支持快速添加、删除、查找数据,可以通过灵活调整索引结点个数和数据个数之间的比例,平衡索引对内存的消耗及其查询效率。Redis 中的有序集合是用跳表来构建的。 78 | 79 | **布隆过滤器**有一定的判错率,但内存占用非常少。针对数据构建一个布隆过滤器后,查询时可以先通过布隆过滤器,判定是否存在。被布隆过滤器判定数据不存在,就没有必要读取磁盘中的索引了。所以,布隆过滤器可以作为 辅助索引,加速查找效率。 80 | 81 | **有序数组**可以作为静态数据的索引,利用二分查找算法可以快速查找数据。 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /docs/31.并行算法.md: -------------------------------------------------------------------------------- 1 | # 并行算法:利用并行处理提高算法的执行效率 2 | 3 | 时间复杂度是衡量算法执行效率的一种标准。但是,时间复杂度并不能跟性能划等号。在真实的软件开发中,即便在不降低时间复杂度的情况下,也可以通过一些优化手段,提升代码的执行效率。对于实际的软件开发来说,即便是像 10%、20% 这样微小的性能提升,也是非常可观的。 4 | 5 | 并行计算是一个工程上的实现思路,尽管跟算法关系不大,但是,在实际的软件开发中,它确实可以非常巧妙地提高程序的运行效率,是一种非常好用的性能优化手段。 6 | 7 | 特别是,当要处理的数据规模达到一定程度之后,无法通过继续优化算法,来提高执行效率 的时候就需要在实现的思路上做文章,利用更多的硬件资源,来加快执行的效率。所以,在很多超大规模数据处理中,并行处理的思想,应用非常广泛,比如 MapReduce 实际上就是一种并行计算框架。 8 | 9 | ## 并行排序 10 | 11 | **第一种是对归并排序并行化处理**。可以将8GB 的待排序的数据划分成 16 个小的数据集合,每个集合包含 500MB 的数据。用 16 个线程,并行地对这 16 个 500MB 的数据集合进行排序。分别排序完成之后,再将这 16 个有序集合合并。 12 | 13 | **第二种是对快速排序并行化处理**。通过扫描一遍数据,找到数据所处的范围区间。把这个区间从小到大划分成 16 个小区间。将 8GB 的数据划分到对应的区间中。针对这 16 个小区间的数据,启动 16 个线程,并行地进行排序。等到 16 个线程都执行结束之后,得到的数据就是有序数据了。 14 | 15 | 这两种处理思路都是分治的思想,对数据进行分片,然后并行处理。区别在于,第一种处理思路是先随意地对数据分片,排序之后再合并。第二种处理思路是先对数据按照大小划分区间,然后再排序,排完序就不需要再处理了。 16 | 17 | ## 并行查找 18 | 19 | 我们知道,散列表是一种非常适合快速查找的数据结构。 20 | 21 | 可以将数据随机分割成 k 份(比如 16 份),每份中的数据只有原来的 1/k,然后针对这 k 个小数据集合分别构建散列表。这样,当某个小散列表的装载因子过大的时候,可以单独对这个散列表进行扩容,而其他散列表不需要进行扩容。 22 | 23 | 还是刚才那个例子,假设现在有 2GB 的数据,我们放到 16 个散列表中,每个散列表中的数据大约是 150MB。当某个散列表需要扩容的时候,我们只需要额外增加 150*0.5=75MB 的内存(假设还是扩容到原来的 1.5 倍)。不管从扩容的执行效率还是内存的利用率上,这种多个小散列表的处理方法,都要比大散列表高效。 24 | 25 | 要查找某个数据的时候,只需要通过 16 个线程,并行地在这 16 个散列表中查找数据。 26 | 27 | 往散列表中添加数据的时候,可以选择将这个新数据放入装载因子最小的那个散列表中,这样有助于减少散列冲突。 28 | 29 | ## 并行字符串匹配 30 | 31 | 在文本中查找某个关键词可以通过字符串匹配算法KMP、BM、RK、BF 等来实现。 32 | 33 | 对于很长的超级大的文本,如何并行处理加快匹配速度呢? 34 | 35 | 可以把大的文本,分割成 k 个小文本。然后启动 k 个线程,并行地在这 k个小文本中查找关键词,再在每个小文本的结尾和开始各取关键词的长度重新查找一遍即可。 36 | 37 | 假设关键词的长度是 m。在每个小文本的结尾和开始各取 m 个字符串。前一个小文本的末尾 m 个字符和后一个小文本的开头 m 个字符,组成一个长度是 2m 的字符串。再拿关键词,在这个长度为 2m 的字符串中再重新查找一遍。 38 | 39 | ## 并行搜索 40 | 41 | 对于广度优先搜索算法,也可以将其改造成并行算法。 42 | 43 | 广度优先搜索是一种逐层搜索的搜索策略。基于当前这一层顶点,可以启动多个线程,并行地搜索下一层的顶点。只需增加至使用两个队列来完成扩展顶点的工作。 44 | 45 | 假设这两个队列分别是队列 A 和队列 B。多线程并行处理队列 A 中的顶点,并将扩展得到的顶点存储在队列 B 中。等队列 A 中的顶点都扩展完成之后,队列 A 被清空,再并行地扩展队列 B 中的顶点,并将扩展出来的顶点存储在队列 A。这样两个队列循环使用,就可以实现并行广度优先搜索算法。 46 | 47 | 48 | 49 | 50 | 51 | ## 并行执行有依赖关系的任务 52 | 53 | 假设n 个任务之间又有一定的依赖关系,如何根据依赖关系找出可以并行执行的任务? 54 | 55 | 答:将任务之间的依赖关系存储为有向图,然后用拓扑排序中的Kahn算法的思想来执行任务。 56 | 57 | 首先,初始化统计每个顶点(任务)的入度。 58 | 59 | 然后,将所有入度为0的顶点(任务)加入到队列A中,启动线程池开始执行队列A中的任务, 每处理完一个任务则将这个任务对应的顶点从队列中移除,并把这个顶点可达的顶点的入度都减 1,发现某个顶点入度为0时,将该顶点添加到队列B中。 60 | 61 | 待线程池执行结束,队列A为空时,再启动线程池开始执行队列B中的任务,两个队列循环使用,重复上面的步骤,直到另一个队列也为空时,结束循环。 62 | 63 | 此时所有任务跑完。 64 | 65 | -------------------------------------------------------------------------------- /docs/32.Redis用到的数据结构.md: -------------------------------------------------------------------------------- 1 | # Redis 中的常用数据类型,底层都是用哪种数据结构实现的? 2 | 3 | Redis 中常用数据类型底层依赖的数据结构,大概有这五种:**压缩列表**(一种特殊的数组)、**有序数组**、**链表**、**散列表**、**跳表**。实际上,Redis 就是这些常用数据结构的封装。 4 | 5 | ## Redis数据库 6 | 7 | Redis 是一种键值(Key-Value)数据库。相对于关系型数据库(比如 MySQL),Redis 也被叫作**非关系型数据库**。 8 | 9 | Redis 中只包含“键”和“值”两部分,只能通过“键”来查询“值”,主要是作为内存数据库来使用,但也支持将数据存储在硬盘中。 10 | 11 | Redis 中,键的数据类型是字符串,值的数据类型常用的有字符串、列表、字典、集合、有序集合。 12 | 13 | ## 列表(list) 14 | 15 | 这种数据类型对应两种实现方法,一种是**压缩列表**(ziplist),另一种是双向循环链表。 16 | 17 | 当列表中存储的数据量比较小并满足下面条件时,就使用压缩列表实现: 18 | 19 | - 列表中保存的单个数据(有可能是字符串类型的)小于 64 字节; 20 | - 列表中数据个数少于 512 个。 21 | 22 | 压缩列表,是Redis自己设计的一种数据存储结构。它类似数组通过连续的内存空间来存储数据,但与数组的区别是每个元素存储空间的长度不一样,需要一个位置来记录接下来存储多长: 23 | 24 | ![1570510971957](imgs/3/1570510971957.png) 25 | 26 | 压缩列表的压缩两字是相对数组而言的,数组要求每个元素的大小相同,如果要存储不同长度的字符串,那就需要用最大长度的字符串大小作为元素的大小(假设是 20 个字节)。存储小于 20 个字节长度的字符串的时候,便会浪费部分存储空间。 27 | 28 | ![1570510987625](imgs/3/1570510987625.png) 29 | 30 | 压缩列表这种存储结构,一方面比较节省内存,另一方面可以支持不同类型数据的存储。而且,因为数据存储在一片连续的内存空间,通过键来获取值为列表类型的数据,读取的效率也非常高。 31 | 32 | **当列表中存储的数据量比较大不能满足上面两个条件的时候,列表就要通过双向循环链表来实现了。** 33 | 34 | Redis的双向链表实现时,额外定义了一个list结构体来组织链表的首、尾指针,还有长度等信息: 35 | 36 | ```c 37 | // 以下是 C 语言代码,因为 Redis 是用 C 语言实现的。 38 | typedef struct listnode { 39 | struct listNode *prev; 40 | struct listNode *next; 41 | void *value; 42 | } listNode; 43 | 44 | typedef struct list { 45 | listNode *cls; 46 | listNode *tail; 47 | unsigned long len; 48 | // .... 省略其他定义 49 | } list; 50 | ``` 51 | 52 | ## 字典(hash) 53 | 54 | 字典类型用来存储一组数据对,即键值两部分的键值对。 55 | 56 | redis的字典类型有**压缩列表**和**散列表**两种实现方式。 57 | 58 | 只有当存储的数据量比较小的情况下,Redis才使用压缩列表来实现字典类型。具体需要满足两个条件: 59 | 60 | - 字典中保存的键和值的大小都要小于 64 字节; 61 | - 字典中键值对的个数要小于 512 个。 62 | 63 | 当不能同时满足上面两个条件的时候,Redis就使用散列表来实现字典类型。 64 | 65 | Redis的中的散列表使用[MurmurHash2](https://zh.wikipedia.org/wiki/Murmur哈希)哈希算法作为哈希函数,使用链表法来解决哈希冲突问题,支持散列表的动态扩容、缩容。当装载因子大于 1 的时候,Redis 会触发扩容,将散列表扩大为原来大小的 2 倍左右。当数据动态减少装载因子小于 0.1 的时候,Redis 就会触发缩容,缩小为字典中数据个数的大约 2 倍大小。 66 | 67 | Redis使用渐进式扩容缩容策略,将数据的搬移分批进行,避免了大量数据一次性搬移导致的服务停顿。 68 | 69 | ## 集合(set) 70 | 71 | 集合这种数据类型用来存储一组不重复的数据。这种数据类型有序数组和散列表两种实现方法。 72 | 73 | 当要存储的数据,同时满足下面这样两个条件的时候,Redis 就采用有序数组来实现集合: 74 | 75 | - 存储的数据都是整数; 76 | - 存储的数据元素个数不超过 512 个。 77 | 78 | 当不能同时满足这两个条件的时候,Redis 就使用散列表来存储集合中的数据。 79 | 80 | ## 有序集合(sortedset) 81 | 82 | 有序集合这种数据类型,存储的每个数据会附带一个得分。通过得分的大小将数据组织成跳表,以支持快速地按照得分值、得分区间获取数据。 83 | 84 | 有序集合在数据量比较小的时候,也会用压缩列表来实现,条件是: 85 | 86 | - 所有数据的大小都要小于 64 字节; 87 | - 元素个数要小于 128 个。 88 | 89 | ## 数据结构持久化 90 | 91 | 将Redis内存中的数据存储到硬盘中,这样当机器断电后,数据并不会丢失。在机器重新启动之后,Redis 只需要再将存储在硬盘中的数据,重新读取到内存即可。 92 | 93 | 将Redis中跟具体内存地址有关的数据结构存储到磁盘,叫作**数据结构的持久化问题**,或者**对象的持久化问题**。这里的“持久化”,可以笼统地可以理解为“存储到磁盘”。 94 | 95 | 数据结构的持久化主要有两种解决思路: 96 | 97 | 第一种是清除原有的存储结构,只将数据存储到磁盘中。从磁盘还原数据到内存的时候,再重新将数据组织成原来的数据结构。 98 | 99 | 第二种方式是保留原来的存储格式,将数据按照原有的格式存储在磁盘中。对于散列表,可以将散列表的大小、每个数据被散列到的槽的编号等信息,都保存在磁盘中。有了这些信息从磁盘中将数据还原到内存中的时候,就可以避免重新计算哈希值。 100 | 101 | 102 | 103 | **第一种方式的弊端**:数据从硬盘还原到内存的过程,会耗用比较多的时间。比如,从磁盘中取出数据重新构建散列表的时候,需要重新计算每个数据的哈希值。如果磁盘中存储的是几 GB 的数据,那重构数据结构的耗时就不可忽视了。 104 | 105 | 106 | -------------------------------------------------------------------------------- /docs/36.短网址服务系统.md: -------------------------------------------------------------------------------- 1 | # 短网址服务系统 2 | 3 | 比如在微博里发布一条带网址的信息,微博会把里面的网址转化成一个更短的网址,只要访问这个短网址,就相当于访问原始的网址。 4 | 5 | 从功能上讲,短网址服务其实就是把一个长的网址转化成一个短的网址。 6 | 7 | ## 短网址服务整体介绍 8 | 9 | 短网址服务的一个核心功能就是把原始的长网址转化成短网址。 10 | 11 | ![1570511733024](imgs/3/1570511733024.png) 12 | 13 | 浏览器会先访问短网址服务,短网址服务返回原始网址给游览器,游览器识别到重定向语法再去访问原始网址。 14 | 15 | 下面将讲到短网址服务的两种实现方法: 16 | 17 | 第一种实现思路是通过哈希算法生成短网址。采用MurmurHash 算法,并将计算得到的 10 进制数,转化成 62 进制表示法,进一步缩短短网址的长度。对于哈希算法的哈希冲突问题,通过给原始网址添加特殊前缀字符,重新计算哈希值的方法来解决。 18 | 19 | 第二种实现思路是通过 ID 生成器来生成短网址。维护一个 ID 自增的 ID 生成器,给每个原始网址分配一个 ID 号码,并且同样转成 62 进制表示法,拼接到短网址服务的域名之后,形成最终的短网址。 20 | 21 | ## 哈希算法生成短网址 22 | 23 | 哈希算法可以将一个不管多长的字符串,转化成一个长度固定的哈希值,所以可以利用哈希算法来生成短网址。 24 | 25 | 在生成短网址这个问题上,只需要关心哈希算法的计算速度和冲突概率。能够满足这样要求的哈希算法有很多,其中比较著名并且应用广泛的一个哈希算法,那就是[MurmurHash 算法](https://zh.wikipedia.org/wiki/Murmur哈希)。尽管这个哈希算法在 2008 年才被发明出来,但现在它已经广泛应用到 Redis、MemCache、Cassandra、HBase、Lucene 等众多著名的软件中。 26 | 27 | MurmurHash 算法提供了两种长度的哈希值,一种是 32bits,一种是 128bits。为了让最终生成的短网址尽可能短,可以选择 32bits 的哈希值。为了让32bits 表示的字符串的更短,可以用0~9、a~z、A~Z组合的62进制表示。具体计算方法是将32bits的数字用10进制表示,然后不断62取余数。 28 | 29 | ![1570511752337](imgs/3/1570511752337.png) 30 | 31 | ### 解决哈希冲突问题 32 | 33 | 尽管MurmurHash算法,冲突的概率非常低。但是一旦冲突就会导致两个原始网址被转化成同一个短网址。 34 | 35 | 当有一个新的原始网址需要生成短网址的时候,先利用 MurmurHash 算法,生成短网址。然后拿这个生成的短网址,在数据库中查找。如果找到了相同的短网址,那就将这个短网址对应的原始网址取出来。如果数据库存储的这个短网址对应的原始网址,跟现在正在处理的原始网址是一样的,就可以拿这个短网址直接用。 36 | 37 | 如果数据库中记录的原始网址,跟正在处理的原始网址不一样,那就说明哈希算法发生了冲突。此时给原始网址拼接一串特殊字符,比如“[DUPLICATED]”,再重新计算哈希值,生成短网址,重复上面的步骤。 38 | 39 | 假设出现非常极端的情况,又发生冲突了,可以再换一个拼接字符串,比如“[FUCK]”,再计算哈希值。然后把计算得到的哈希值,跟原始网址拼接了特殊字符串之后的文本,一并存储在 MySQL 数据库中。 40 | 41 | 当用户访问短网址的时候,短网址服务先通过短网址,在数据库中查找到对应的原始网址。如果原始网址有拼接特殊字符,就先将特殊字符去掉,然后再将不包含特殊字符的原始网址返回给浏览器。 42 | 43 | ### 优化哈希算法生成短网址的性能 44 | 45 | 在短网址生成的过程中,需要跟数据库打两次交道,也就是会执行两条 SQL 语句。第一个 SQL 语句是通过短网址查询短网址与原始网址的对应关系,第二个 SQL 语句是将新生成的短网址和原始网址之间的对应关系存储到数据库。 46 | 47 | 两条 SQL 语句的执行需要两次网络通信。这种 IO 通信耗时以及 SQL 语句的执行,才是整个短网址服务的性能瓶颈所在。所以,为了提高性能,需要尽量减少 SQL 语句。将短网址字段设置为主键,这样能自动添加索引还能要求不重复。 48 | 49 | 把已经生成的短网址,构建成布隆过滤器。布隆过滤器是比较节省内存的一种存储结构,长度是 10 亿的布隆过滤器,也只需要 125MB 左右的内存空间。 50 | 51 | 当有新的短网址生成的时候,先拿这个新生成的短网址,在布隆过滤器中查找。如果查找的结果是不存在,那就说明这个新生成的短网址并没有冲突。此时直接将生成的短网址与对应的原始网址,尝试存储到数据库中。 52 | 53 | 如果布隆过滤器出现误判,数据库反馈违反唯一性索引异常,那就重新执行上面讲到的“查询、写入”过程。由于设计良好的布隆过滤器误判率极低,基本只需要执行一条写入的 SQL 语句就可以了。 54 | 55 | 56 | 57 | ## ID生成器生成短网址 58 | 59 | 维护一个 ID 自增生成器,它可以生成 1、2、3…这样自增的整数 ID。当短网址服务接收到一个原始网址转化成短网址的请求之后,它先从 ID 生成器中取一个号码,然后将其转化成 62 进制表示法,拼接到短网址服务的域名(比如http://t.cn/)后面,就形成了最终的短网址。最后把生成的短网址和对应的原始网址存储到数据库中。 60 | 61 | ### 相同原始网址可能对应不同的短网址的处理方式 62 | 63 | 直接这种方式可能会导致相同的原始网址对应不同的短网址,有允许和不允许两种处理方式: 64 | 65 | **1.允许相同的原始网址对应不同的短网址** 66 | 67 | 实际上,相同的原始网址对应不同的短网址,这个用户是可以接受的。在大部分短网址的应用场景里,用户只关心短网址能否正确地跳转到原始网址。至于短网址长什么样子,其实根本就不关心。所以,即便是同一个原始网址,两次生成的短网址不一样,也并不会影响到用户的使用,所以不做处理也无妨。 68 | 69 | **2.一个原始网址只能对应唯一的一个短网址** 70 | 71 | 给一个原始网址生成短网址的时候,先拿原始网址在数据库中查找。如果数据库中已经存在,那就取出对应的短网址,直接返回给用户;否则将短网址插入到数据库。 72 | 73 | 不过,这样导致需要给数据库中的短网址和原始网址这两个字段,都添加索引。短网址字段加索引是为了提高用户查询短网址对应的原始网页的速度;原始网址字段加索引是为了加快刚刚讲的通过原始网址查询短网址的速度。 74 | 75 | 代价是两个索引需要占用更多的存储空间,还会导致插入、删除等操作性能的下降。 76 | 77 | ### 提高ID生成器的性能 78 | 79 | 实现 ID 生成器的最简单的方法是利用数据库自增字段。 80 | 81 | 如果自己维护一个计数器,如何提高 ID生成器的并发性能呢? 82 | 83 | 1.可以给 ID 生成器装多个前置发号器,批量地给每个前置发号器发送 ID 号码。接受到短网址生成请求的时候,就选择一个前置发号器来取号码。这样通过多个前置发号器,明显提高了并发发号的能力。 84 | 85 | ![1570511775562](imgs/3/1570511775562.png) 86 | 87 | 2.直接实现多个 ID 生成器同时服务。为了保证每个 ID 生成器生成的 ID 不重复。要求每个 ID 生成器按照一定的规则,来生成 ID 号码。比如: 88 | 89 | ![1570511790220](imgs/3/1570511790220.png) 90 | 91 | 这样通过多个 ID 生成器同时工作,也提高了 ID 生成的效率。 -------------------------------------------------------------------------------- /docs/37.权衡选择数据结构和算法.md: -------------------------------------------------------------------------------- 1 | # 在实际开发中,如何权衡选择使用哪种数据结构和算法? 2 | 3 | 工程上的问题在选择数据结构和算法的时候,往往需要综合各种因素,比如编码难度、维护成本、数据特征、数据规模等,最终选择一个**工程的最合适解**,而非**理论上的最优解**。下面是关于这个问题的一些经验: 4 | 5 | ## 1. 时间、空间复杂度不能跟性能划等号 6 | 7 | 复杂度不能与性能简单划等号,不能表示执行时间和内存消耗的确切数据量。 8 | 9 | **复杂度不是执行时间和内存消耗的精确值** 10 | 11 | 在用大 O 表示法表示复杂度的时候,会忽略掉低阶、常数、系数,只保留高阶,并且它的度量单位是语句的执行频度。每条语句的执行时间,并非是相同、确定的。所以,复杂度给出的只能是一个非精确量值的趋势。 12 | 13 | **代码的执行时间有时不跟时间复杂度成正比** 14 | 15 | 时间复杂度是 O(nlogn) 的算法比时间复杂度是 O(n^2) 的算法执行效率要高,这样说的一个前提是,算法处理的是大规模数据的情况。对于小规模数据的处理,算法的执行效率并不一定跟时间复杂度成正比,有时还会跟复杂度成反比。 16 | 17 | **对于处理不同问题的不同算法,其复杂度大小没有可比性** 18 | 19 | 复杂度只能用来表征不同算法,在处理同样的问题,以及同样数据类型的情况下的性能表现。但是,对于不同的问题、不同的数据类型,不同算法之间的复杂度大小并没有可比性。 20 | 21 | ## 2. 抛开数据规模谈数据结构和算法都是“耍流氓” 22 | 23 | 在平时的开发中,在数据规模很小的情况下,普通算法和高级算法之间的性能差距会非常小。如果代码执行频率不高、又不是核心代码,这时选择数据结构和算法的主要依据是,其是否简单、容易维护、容易实现。大部分情况下,直接用最简单的存储结构和最暴力的算法就可以了。 24 | 25 | 比如,对于长度在一百以内的字符串匹配,直接使用朴素的字符串匹配算法就够了。如果用 KMP、BM 这些更加高效的字符串匹配算法,实际上就大材小用了。因为这对于处理时间是毫秒量级敏感的系统来说,性能的提升并不大。相反,这些高级算法会徒增编码的难度,还容易产生 bug。 26 | 27 | ## 3. 结合数据特征和访问方式来选择数据结构 28 | 29 | 面对实际的软件开发场景,最考验能力的并不是数据结构和算法本身,而是对问题需求的挖掘、抽象、建模。 30 | 31 | **如何将一个背景复杂、开放的问题,通过细致的观察、调研、假设,理清楚要处理数据的特征与访问方式,这才是解决问题的重点。**只有理清楚了这些东西,才能将问题转化成合理的数据结构模型,进而找到满足需求的算法。 32 | 33 | Trie 树这种数据结构是一种非常高效的字符串匹配算法。但如果你要处理的数据,并没有太多的前缀重合,并且字符集很大,显然就不适合利用 Trie 树了。所以,在用 Trie 树之前需要详细地分析数据的特点,甚至还要写些分析代码、测试代码,明确要处理的数据是否适合使用 Trie 树这种数据结构。 34 | 35 | 再比如,图的表示方式有很多种,邻接矩阵、邻接表、逆邻接表、二元组等等。你面对的场景应该用哪种方式来表示,具体还要看你的数据特征和访问方式。如果每个数据之间联系很少,对应到图中,就是一个稀疏图,就比较适合用邻接表来存储。相反,如果是稠密图,那就比较适合采用邻接矩阵来存储。 36 | 37 | ## 4. 区别对待IO密集、内存密集和计算密集 38 | 39 | 如果要处理的数据存储在磁盘,比如数据库中。那代码的性能瓶颈有可能在磁盘IO,而并非算法本身。这时需要合理地选择数据存储格式和存取方式,减少磁盘IO的次数。 40 | 41 | 在[递归-如何用三行代码找到“最终推荐人”?](06.递归.md#如何用三行代码找到"最终推荐人"?)中讲到最终推荐人的例子,如果某个用户是经过层层推荐才来注册的,那获取他的最终推荐人的时候,就需要多次访问数据库,性能显然就不高了。 42 | 43 | 其实可以事先离线计算每个用户的最终推荐人,并且保存在表中的某个字段里。当需要查看某个用户的最终推荐人的时候,访问一次数据库就可以获取到。因为某个用户的最终推荐人一旦确定,就不会变动。 44 | 45 | 如果数据是存储在内存中,还需要考虑代码是内存密集型的还是CPU密集型的。 46 | 47 | CPU密集型,是指代码执行效率的瓶颈主要在 CPU 执行的效率。从内存中读取一次数据,到 CPU 缓存或者寄存器之后,会进行多次频繁的 CPU 计算(比如加减乘除),CPU 计算耗时占大部分。所以,在选择数据结构和算法的时候,要尽量减少逻辑计算的复杂度。比如,用位运算代替加减乘除运算等。 48 | 49 | 内存密集型,是指代码执行效率的瓶颈在内存数据的存取。对于内存密集型的代码,计算操作都比较简单,比如,字符串比较操作,实际上就是内存密集型的。每次从内存中读取数据之后,只需要进行一次简单的比较操作。所以内存数据的读取速度,是字符串比较操作的瓶颈。因此,在选择数据结构和算法的时候,需要考虑是否能减少数据的读取量,数据是否在内存中连续存储,是否能利用CPU缓存预读。 50 | 51 | ## 5. 善用语言提供的类,避免重复造轮子 52 | 53 | 对于大部分常用的数据结构和算法,编程语言都提供了现成的类和函数实现。比如,Java 中的 HashMap 就是散列表的实现,TreeMap 就是红黑树的实现等。在实际的软件开发中,除非有特殊的要求都可以直接使用编程语言中提供的这些类或函数。 54 | 55 | 这些编程语言提供的类和函数,都是经过无数验证过的,不管是正确性、鲁棒性,都要超过自己造的轮子。而且,重复造轮子,需要写大量的测试用例,并且考虑各种异常情况,还要团队能看懂、能维护。这显然是一个出力不讨好的事情。这也是很多高级的数据结构和算法,比如 Trie 树、跳表等,在工程中,并不经常被应用的原因。 56 | 57 | 但这并不代表,学习数据结构和算法是没用的。深入理解原理,有助于更好地应用这些编程语言提供的类和函数。能否深入理解所用工具、类的原理,这也是普通程序员跟技术专家的区别。 58 | 59 | ## 6. 千万不要漫无目的地过度优化 60 | 61 | 掌握了数据结构和算法这把锤子,不要看哪里都是钉子。比如,一段代码执行只需要 0.01 秒,你非得用一个非常复杂的算法或者数据结构,将其优化成 0.005 秒。即便你的算法再优秀,这种微小优化的意义也并不大。相反,对应的代码维护成本可能要高很多。 62 | 63 | 不过度优化并不代表,在软件开发的时候,可以不加思考地随意选择数据结构和算法。估算能力实际上也是一个非常重要的能力,不仅要对普通情况下的数据规模和性能压力做估算,还需要对异常以及将来一段时间内,可能达到的数据规模和性能压力做估算。这样才能做到未雨绸缪,写出来的代码才能经久可用。 64 | 65 | 还有,当你真的要优化代码的时候,一定要先做 Benchmark 基准测试。这样才能避免你想当然地换了一个更高效的算法,但真实情况下,性能反倒下降了。 66 | 67 | ## 总结 68 | 69 | ![1574085510892](imgs/1574085510892.png) 70 | 71 | 在利用数据结构和算法解决问题的时候,一定要先分析清楚问题的需求、限制、隐藏的特点等。只有搞清楚了这些,才能有针对性地选择恰当的数据结构和算法。这种灵活应用的实战能力,需要长期的刻意锻炼和积累。这是一个有经验的工程师和一个学院派的工程师的区别。 -------------------------------------------------------------------------------- /docs/_coverpage.md: -------------------------------------------------------------------------------- 1 | 2 | # 《数据结构与算法之美》 3 | 4 | 本文档是[《数据结构与算法之美》](http://gk.link/a/108GK)的学习笔记和个人编写的python实现的相关代码。 5 | 6 | 每一课最后出的思考题均有相应的解答和**python代码实现**。 7 | 8 | [![stars](https://badgen.net/github/stars/xiao-xiaoming/DataStructure-BeautyOfAlgorithm?icon=github&color=4ab8a1)](https://github.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm) [![forks](https://badgen.net/github/forks/xiao-xiaoming/DataStructure-BeautyOfAlgorithm?icon=github&color=4ab8a1)](https://github.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm) 9 | 10 | 如果本文档对您有用,期待您进入github项目主页点击右上角Star :star: 给予关注!谢谢拉! 11 | 12 | 还可以分享给您身边更多的小伙伴!:kissing_heart: 13 | 14 | [GitHub]() 15 | [开始阅读](README.md) 16 | 17 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | * **入门篇** 2 | * [01.入门篇](01.入门篇.md) 3 | 4 | 5 | 6 | * **基础篇** 7 | * [02.数组](02.数组.md) 8 | * [03.链表](03.链表.md) 9 | * [04.栈](04.栈.md) 10 | * [05.队列](05.队列.md) 11 | * [06.递归](06.递归.md) 12 | * [07.排序](07.排序.md) 13 | * [09.二分查找](09.二分查找.md) 14 | * [10.跳表](10.跳表.md) 15 | * [11.散列表](11.散列表.md) 16 | * [12.哈希算法](12.哈希算法.md) 17 | * [13.二叉树基础](13.二叉树基础.md) 18 | * [14.红黑树](14.红黑树.md) 19 | * [15.递归树](15.递归树.md) 20 | * [16.堆](16.堆.md) 21 | * [17.图的表示](17.图的表示.md) 22 | * [18.深度和广度优先搜索](18.深度和广度优先搜索.md) 23 | * [19.字符串匹配基础](19.字符串匹配基础.md) 24 | * [20.Trie树](20.Trie树.md) 25 | * [21.AC自动机](21.AC自动机.md) 26 | * [22.贪心算法](22.贪心算法.md) 27 | * [23.分治算法](23.分治算法.md) 28 | * [24.回溯算法](24.回溯算法.md) 29 | * [25.动态规划](25.动态规划.md) 30 | 31 | 32 | 33 | * **高级篇** 34 | * [26.拓扑排序](26.拓扑排序.md) 35 | * [27.有权图的应用:最短路径](27.有权图的应用:最短路径.md) 36 | * [28.位图&布隆过滤器](28.位图&布隆过滤器.md) 37 | * [29.B+树](29.B+树.md) 38 | * [30.索引](30.索引.md) 39 | * [31.并行算法](31.并行算法.md) 40 | 41 | 42 | 43 | * **实战篇** 44 | 45 | * [32.Redis用到的数据结构](32.Redis用到的数据结构.md) 46 | * [33.搜索引擎的理论基础](33.搜索引擎的理论基础.md) 47 | * [34.高性能队列Disruptor](34.高性能队列Disruptor.md) 48 | * [35.微服务的鉴权限流接口](35.微服务的鉴权限流接口.md) 49 | * [36.短网址服务系统](36.短网址服务系统.md) 50 | 51 | 52 | 53 | * **结束篇** 54 | * [37.权衡选择数据结构和算法](37.权衡选择数据结构和算法.md) 55 | * [38.leetcode练习题](38.leetcode练习题.md) 56 | 57 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/favicon.ico -------------------------------------------------------------------------------- /docs/imgs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1.jpg -------------------------------------------------------------------------------- /docs/imgs/1475054023258693.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1475054023258693.jpg -------------------------------------------------------------------------------- /docs/imgs/1570439941723.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570439941723.png -------------------------------------------------------------------------------- /docs/imgs/1570507062242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570507062242.png -------------------------------------------------------------------------------- /docs/imgs/1570507106426.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570507106426.png -------------------------------------------------------------------------------- /docs/imgs/1570507123681.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570507123681.png -------------------------------------------------------------------------------- /docs/imgs/1570684986266.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570684986266.png -------------------------------------------------------------------------------- /docs/imgs/1570723469548.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570723469548.png -------------------------------------------------------------------------------- /docs/imgs/1570723505115.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1570723505115.png -------------------------------------------------------------------------------- /docs/imgs/1571040886966.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1571040886966.png -------------------------------------------------------------------------------- /docs/imgs/1571226184051.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1571226184051.png -------------------------------------------------------------------------------- /docs/imgs/1571227085370.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1571227085370.png -------------------------------------------------------------------------------- /docs/imgs/1571762267701.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1571762267701.png -------------------------------------------------------------------------------- /docs/imgs/1572778109574.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1572778109574.png -------------------------------------------------------------------------------- /docs/imgs/1572782164334.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1572782164334.png -------------------------------------------------------------------------------- /docs/imgs/1572834037956.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1572834037956.png -------------------------------------------------------------------------------- /docs/imgs/1572834957032.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1572834957032.png -------------------------------------------------------------------------------- /docs/imgs/1573352954856.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1573352954856.png -------------------------------------------------------------------------------- /docs/imgs/1573896556022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1573896556022.png -------------------------------------------------------------------------------- /docs/imgs/1574073361716.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1574073361716.jpg -------------------------------------------------------------------------------- /docs/imgs/1574085510892.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/1574085510892.png -------------------------------------------------------------------------------- /docs/imgs/2/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1.jpg -------------------------------------------------------------------------------- /docs/imgs/2/1570432607992.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570432607992.png -------------------------------------------------------------------------------- /docs/imgs/2/1570432750746.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570432750746.png -------------------------------------------------------------------------------- /docs/imgs/2/1570432783901.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570432783901.png -------------------------------------------------------------------------------- /docs/imgs/2/1570432823131.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570432823131.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433001763.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433001763.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433061344.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433061344.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433080092.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433080092.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433106298.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433106298.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433133761.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433133761.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433152459.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433152459.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433167414.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433167414.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433190306.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433190306.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433217183.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433217183.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433339703.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433339703.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433366474.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433366474.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433383574.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433383574.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433406655.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433406655.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433422411.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433422411.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433438772.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433438772.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433457896.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433457896.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433479539.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433479539.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433507770.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433507770.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433522754.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433522754.png -------------------------------------------------------------------------------- /docs/imgs/2/1570433907877.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570433907877.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434107982.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434107982.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434132748.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434132748.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434178012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434178012.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434192005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434192005.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434207006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434207006.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434239490.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434239490.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434286245.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434286245.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434301993.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434301993.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434319108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434319108.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434336773.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434336773.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434356028.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434356028.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434375850.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434375850.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434553802.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434553802.png -------------------------------------------------------------------------------- /docs/imgs/2/1570434823959.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570434823959.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439501672.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439501672.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439557784.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439557784.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439590377.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439590377.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439607551.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439607551.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439636166.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439636166.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439866145.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439866145.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439893869.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439893869.png -------------------------------------------------------------------------------- /docs/imgs/2/1570439941723.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570439941723.png -------------------------------------------------------------------------------- /docs/imgs/2/1570440486953.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570440486953.png -------------------------------------------------------------------------------- /docs/imgs/2/1570440501975.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570440501975.png -------------------------------------------------------------------------------- /docs/imgs/2/1570441637365.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570441637365.png -------------------------------------------------------------------------------- /docs/imgs/2/1570441654764.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570441654764.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442602270.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442602270.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442615779.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442615779.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442649156.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442649156.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442675055.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442675055.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442695929.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442695929.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442729225.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442729225.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442776661.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442776661.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442793990.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442793990.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442809447.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442809447.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442938362.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442938362.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442960343.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442960343.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442976703.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442976703.png -------------------------------------------------------------------------------- /docs/imgs/2/1570442999808.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570442999808.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443033230.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443033230.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443204350.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443204350.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443225487.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443225487.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443243282.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443243282.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443319623.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443319623.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443360066.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443360066.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443376432.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443376432.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443391552.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443391552.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443537331.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443537331.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443554236.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443554236.png -------------------------------------------------------------------------------- /docs/imgs/2/1570443690705.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570443690705.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444279777.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444279777.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444335291.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444335291.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444363236.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444363236.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444377068.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444377068.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444390843.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444390843.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444403668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444403668.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444415962.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444415962.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444429469.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444429469.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444448382.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444448382.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444524770.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444524770.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444541558.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444541558.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444560417.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444560417.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444574980.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444574980.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444644303.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444644303.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444657714.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444657714.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444672716.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444672716.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444686811.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444686811.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444901543.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444901543.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444918651.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444918651.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444949922.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444949922.png -------------------------------------------------------------------------------- /docs/imgs/2/1570444992882.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570444992882.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445009767.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445009767.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445028474.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445028474.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445049617.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445049617.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445070428.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445070428.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445087285.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445087285.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445105711.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445105711.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445145477.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445145477.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445163520.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445163520.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445186041.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445186041.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445206401.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445206401.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445220062.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445220062.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445234190.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445234190.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445246373.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445246373.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445651316.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445651316.png -------------------------------------------------------------------------------- /docs/imgs/2/1570445665505.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570445665505.png -------------------------------------------------------------------------------- /docs/imgs/2/1570446242483.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570446242483.png -------------------------------------------------------------------------------- /docs/imgs/2/1570446604211.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570446604211.png -------------------------------------------------------------------------------- /docs/imgs/2/1570448039211.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570448039211.png -------------------------------------------------------------------------------- /docs/imgs/2/1570448501976.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570448501976.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493298643.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493298643.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493443825.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493443825.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493581004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493581004.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493595417.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493595417.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493622909.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493622909.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493638378.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493638378.png -------------------------------------------------------------------------------- /docs/imgs/2/1570493827984.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570493827984.png -------------------------------------------------------------------------------- /docs/imgs/2/1570494076865.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570494076865.png -------------------------------------------------------------------------------- /docs/imgs/2/1570494236321.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570494236321.png -------------------------------------------------------------------------------- /docs/imgs/2/1570494449408.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570494449408.png -------------------------------------------------------------------------------- /docs/imgs/2/1570494627902.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570494627902.png -------------------------------------------------------------------------------- /docs/imgs/2/1570494651114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570494651114.png -------------------------------------------------------------------------------- /docs/imgs/2/1570496431493.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570496431493.png -------------------------------------------------------------------------------- /docs/imgs/2/1570496493417.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570496493417.png -------------------------------------------------------------------------------- /docs/imgs/2/1570496545408.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570496545408.png -------------------------------------------------------------------------------- /docs/imgs/2/1570496832646.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570496832646.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497121476.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497121476.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497151653.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497151653.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497174693.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497174693.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497255139.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497255139.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497334285.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497334285.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497356895.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497356895.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497374244.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497374244.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497713857.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497713857.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497928999.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497928999.png -------------------------------------------------------------------------------- /docs/imgs/2/1570497975150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570497975150.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498286430.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498286430.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498355108.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498355108.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498417310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498417310.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498447098.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498447098.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498470428.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498470428.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498502925.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498502925.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498760377.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498760377.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498774667.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498774667.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498799523.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498799523.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498845772.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498845772.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498875778.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498875778.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498905387.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498905387.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498935264.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498935264.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498956983.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498956983.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498975996.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498975996.png -------------------------------------------------------------------------------- /docs/imgs/2/1570498996673.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570498996673.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499030429.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499030429.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499071780.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499071780.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499164110.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499164110.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499179335.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499179335.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499211481.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499211481.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499239474.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499239474.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499252464.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499252464.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499479897.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499479897.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499526476.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499526476.png -------------------------------------------------------------------------------- /docs/imgs/2/1570499540559.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570499540559.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500434769.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500434769.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500456458.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500456458.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500470544.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500470544.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500495719.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500495719.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500591632.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500591632.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500612306.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500612306.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500742068.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500742068.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500755759.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500755759.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500769943.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500769943.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500782819.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500782819.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500806433.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500806433.png -------------------------------------------------------------------------------- /docs/imgs/2/1570500850207.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570500850207.png -------------------------------------------------------------------------------- /docs/imgs/2/1570501134514.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570501134514.png -------------------------------------------------------------------------------- /docs/imgs/2/1570501292623.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570501292623.png -------------------------------------------------------------------------------- /docs/imgs/2/1570501375909.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570501375909.png -------------------------------------------------------------------------------- /docs/imgs/2/1570501407500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570501407500.png -------------------------------------------------------------------------------- /docs/imgs/2/1570501425196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570501425196.png -------------------------------------------------------------------------------- /docs/imgs/2/1570503357732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570503357732.png -------------------------------------------------------------------------------- /docs/imgs/2/1570503806038.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570503806038.png -------------------------------------------------------------------------------- /docs/imgs/2/1570503949180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570503949180.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504039881.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504039881.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504227618.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504227618.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504409871.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504409871.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504508147.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504508147.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504524638.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504524638.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504543161.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504543161.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504610402.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504610402.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504635185.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504635185.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504645294.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504645294.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504739176.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504739176.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504780404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504780404.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504802113.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504802113.png -------------------------------------------------------------------------------- /docs/imgs/2/1570504823431.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570504823431.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505483818.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505483818.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505502413.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505502413.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505701692.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505701692.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505728487.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505728487.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505743187.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505743187.png -------------------------------------------------------------------------------- /docs/imgs/2/1570505830434.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570505830434.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506063479.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506063479.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506081739.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506081739.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506827342.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506827342.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506847019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506847019.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506862261.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506862261.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506881996.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506881996.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506917393.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506917393.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506939090.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506939090.png -------------------------------------------------------------------------------- /docs/imgs/2/1570506958575.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570506958575.png -------------------------------------------------------------------------------- /docs/imgs/2/1570507062242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570507062242.png -------------------------------------------------------------------------------- /docs/imgs/2/1570507106426.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570507106426.png -------------------------------------------------------------------------------- /docs/imgs/2/1570507123681.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1570507123681.png -------------------------------------------------------------------------------- /docs/imgs/2/1573896556022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/1573896556022.png -------------------------------------------------------------------------------- /docs/imgs/2/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/2.jpg -------------------------------------------------------------------------------- /docs/imgs/2/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/3.jpg -------------------------------------------------------------------------------- /docs/imgs/2/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/4.jpg -------------------------------------------------------------------------------- /docs/imgs/2/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/5.jpg -------------------------------------------------------------------------------- /docs/imgs/2/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/6.jpg -------------------------------------------------------------------------------- /docs/imgs/2/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/2/7.jpg -------------------------------------------------------------------------------- /docs/imgs/3/1570510971957.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570510971957.png -------------------------------------------------------------------------------- /docs/imgs/3/1570510987625.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570510987625.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511130593.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511130593.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511195844.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511195844.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511212559.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511212559.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511230082.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511230082.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511244884.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511244884.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511356767.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511356767.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511408536.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511408536.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511514354.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511514354.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511532621.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511532621.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511548680.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511548680.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511567694.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511567694.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511582543.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511582543.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511599857.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511599857.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511618259.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511618259.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511638896.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511638896.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511733024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511733024.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511752337.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511752337.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511775562.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511775562.png -------------------------------------------------------------------------------- /docs/imgs/3/1570511790220.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/3/1570511790220.png -------------------------------------------------------------------------------- /docs/imgs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/4.jpg -------------------------------------------------------------------------------- /docs/imgs/496275-20180527123823742-514849225.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/496275-20180527123823742-514849225.png -------------------------------------------------------------------------------- /docs/imgs/496275-20180527124958975-24745120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/496275-20180527124958975-24745120.png -------------------------------------------------------------------------------- /docs/imgs/498077-20160822172408386-366341651.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/498077-20160822172408386-366341651.png -------------------------------------------------------------------------------- /docs/imgs/498077-20160822172431933-546286787.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/498077-20160822172431933-546286787.png -------------------------------------------------------------------------------- /docs/imgs/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/5.jpg -------------------------------------------------------------------------------- /docs/imgs/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/6.jpg -------------------------------------------------------------------------------- /docs/imgs/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/7.jpg -------------------------------------------------------------------------------- /docs/imgs/7GJ3DU}2$U2D@T[[C84$[]U.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/7GJ3DU}2$U2D@T[[C84$[]U.png -------------------------------------------------------------------------------- /docs/imgs/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/8.jpg -------------------------------------------------------------------------------- /docs/imgs/8926909-e188847813d04828.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/8926909-e188847813d04828.webp -------------------------------------------------------------------------------- /docs/imgs/Huffman_algorithm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/Huffman_algorithm.gif -------------------------------------------------------------------------------- /docs/imgs/TABLE8.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/TABLE8.JPG -------------------------------------------------------------------------------- /docs/imgs/arr.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/arr.gif -------------------------------------------------------------------------------- /docs/imgs/booklist.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/booklist.jpg -------------------------------------------------------------------------------- /docs/imgs/d9yCzX5UJ6eT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/d9yCzX5UJ6eT.png -------------------------------------------------------------------------------- /docs/imgs/jvm1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/jvm1.jpg -------------------------------------------------------------------------------- /docs/imgs/jvm2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/jvm2.jpg -------------------------------------------------------------------------------- /docs/imgs/jvm3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/jvm3.jpg -------------------------------------------------------------------------------- /docs/imgs/jvm4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/jvm4.jpg -------------------------------------------------------------------------------- /docs/imgs/oOAlvULKOjzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/oOAlvULKOjzy.png -------------------------------------------------------------------------------- /docs/imgs/v2-a576dfe6a192cca2a055ceb59a49ac27_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/v2-a576dfe6a192cca2a055ceb59a49ac27_hd.jpg -------------------------------------------------------------------------------- /docs/imgs/v2-d1ff6d696834fa2d02bcae74b5cbc0af_hd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiao-xiaoming/DataStructure-BeautyOfAlgorithm/905da36c03e13d4c3fff14a8530265d76d66378e/docs/imgs/v2-d1ff6d696834fa2d02bcae74b5cbc0af_hd.jpg -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 数据结构与算法之美 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /docs/sw.js: -------------------------------------------------------------------------------- 1 | /* =========================================================== 2 | * docsify sw.js 3 | * =========================================================== 4 | * Copyright 2016 @huxpro 5 | * Licensed under Apache 2.0 6 | * Register service worker. 7 | * ========================================================== */ 8 | 9 | const RUNTIME = 'docsify' 10 | const HOSTNAME_WHITELIST = [ 11 | self.location.hostname, 12 | 'fonts.gstatic.com', 13 | 'fonts.googleapis.com', 14 | 'unpkg.com' 15 | ] 16 | 17 | // The Util Function to hack URLs of intercepted requests 18 | const getFixedUrl = (req) => { 19 | var now = Date.now() 20 | var url = new URL(req.url) 21 | 22 | // 1. fixed http URL 23 | // Just keep syncing with location.protocol 24 | // fetch(httpURL) belongs to active mixed content. 25 | // And fetch(httpRequest) is not supported yet. 26 | url.protocol = self.location.protocol 27 | 28 | // 2. add query for caching-busting. 29 | // Github Pages served with Cache-Control: max-age=600 30 | // max-age on mutable content is error-prone, with SW life of bugs can even extend. 31 | // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. 32 | // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 33 | if (url.hostname === self.location.hostname) { 34 | url.search += (url.search ? '&' : '?') + 'cache-bust=' + now 35 | } 36 | return url.href 37 | } 38 | 39 | /** 40 | * @Lifecycle Activate 41 | * New one activated when old isnt being used. 42 | * 43 | * waitUntil(): activating ====> activated 44 | */ 45 | self.addEventListener('activate', event => { 46 | event.waitUntil(self.clients.claim()) 47 | }) 48 | 49 | /** 50 | * @Functional Fetch 51 | * All network requests are being intercepted here. 52 | * 53 | * void respondWith(Promise r) 54 | */ 55 | self.addEventListener('fetch', event => { 56 | // Skip some of cross-origin requests, like those for Google Analytics. 57 | if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { 58 | // Stale-while-revalidate 59 | // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale 60 | // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 61 | const cached = caches.match(event.request) 62 | const fixedUrl = getFixedUrl(event.request) 63 | const fetched = fetch(fixedUrl, { cache: 'no-store' }) 64 | const fetchedCopy = fetched.then(resp => resp.clone()) 65 | 66 | // Call respondWith() with whatever we get first. 67 | // If the fetch fails (e.g disconnected), wait for the cache. 68 | // If there’s nothing in cache, wait for the fetch. 69 | // If neither yields a response, return offline pages. 70 | event.respondWith( 71 | Promise.race([fetched.catch(_ => cached), cached]) 72 | .then(resp => resp || fetched) 73 | .catch(_ => { /* eat any errors */ }) 74 | ) 75 | 76 | // Update the cache with the version we fetched (only for ok status) 77 | event.waitUntil( 78 | Promise.all([fetchedCopy, caches.open(RUNTIME)]) 79 | .then(([response, cache]) => response.ok && cache.put(event.request, response)) 80 | .catch(_ => { /* eat any errors */ }) 81 | ) 82 | } 83 | }) -------------------------------------------------------------------------------- /logs/0.log: -------------------------------------------------------------------------------- 1 | 34 2 | 52 3 | 53 -------------------------------------------------------------------------------- /logs/1.log: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | 4 4 | 21 5 | 47 -------------------------------------------------------------------------------- /logs/2.log: -------------------------------------------------------------------------------- 1 | 7 2 | 9 3 | 11 -------------------------------------------------------------------------------- /logs/3.log: -------------------------------------------------------------------------------- 1 | 13 2 | 21 3 | 32 -------------------------------------------------------------------------------- /logs/4.log: -------------------------------------------------------------------------------- 1 | 16 2 | 27 3 | 35 -------------------------------------------------------------------------------- /logs/5.log: -------------------------------------------------------------------------------- 1 | 22 2 | 29 3 | 78 -------------------------------------------------------------------------------- /logs/6.log: -------------------------------------------------------------------------------- 1 | 56 2 | 123 3 | 234 -------------------------------------------------------------------------------- /logs/7.log: -------------------------------------------------------------------------------- 1 | 4 2 | 44 3 | 444 -------------------------------------------------------------------------------- /logs/8.log: -------------------------------------------------------------------------------- 1 | 5 2 | 555 3 | 557 -------------------------------------------------------------------------------- /logs/9.log: -------------------------------------------------------------------------------- 1 | 141 2 | 211 3 | 321 --------------------------------------------------------------------------------