├── README.md ├── assets ├── 数据结构与算法.png ├── 树-中序遍历.gif ├── 树-先序遍历.gif └── 树-后序遍历.gif ├── 分治、回溯.md ├── 哈希表、映射、集合.md ├── 复杂度分析.md ├── 数组、链表、跳表.md ├── 栈、队列、优先队列、双端队列.md ├── 树、二叉树、二叉搜索树.md ├── 泛型递归、树的递归.md ├── 深度优先搜索、广度优先搜索.md ├── 记录.md └── 题解.md /README.md: -------------------------------------------------------------------------------- 1 | 🤠 为了方便讨论,目前题解统一整理在`issues`里面:https://github.com/Jack-cool/js_algorithm/issues 2 | 3 | ![](https://github.com/Jack-cool/js_algorithm/blob/master/assets/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95.png) 4 | -------------------------------------------------------------------------------- /assets/数据结构与算法.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/assets/数据结构与算法.png -------------------------------------------------------------------------------- /assets/树-中序遍历.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/assets/树-中序遍历.gif -------------------------------------------------------------------------------- /assets/树-先序遍历.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/assets/树-先序遍历.gif -------------------------------------------------------------------------------- /assets/树-后序遍历.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/assets/树-后序遍历.gif -------------------------------------------------------------------------------- /分治、回溯.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/分治、回溯.md -------------------------------------------------------------------------------- /哈希表、映射、集合.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/哈希表、映射、集合.md -------------------------------------------------------------------------------- /复杂度分析.md: -------------------------------------------------------------------------------- 1 | ## Big O notation 2 | 3 | - O(1): 常数复杂度 4 | - O(logn): 对数复杂度 5 | - O(n): 线性时间复杂度 6 | - O(n^2): 平方 7 | - O(n^3): 立方 8 | - O(2^n): 指数 9 | - O(n!): 阶乘 10 | 11 | ## 时间复杂度曲线 12 | 13 | ![](https://imgkr.cn-bj.ufileos.com/7e634258-0046-404a-924f-4b1db881b5e4.png) 14 | -------------------------------------------------------------------------------- /数组、链表、跳表.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/数组、链表、跳表.md -------------------------------------------------------------------------------- /栈、队列、优先队列、双端队列.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/栈、队列、优先队列、双端队列.md -------------------------------------------------------------------------------- /树、二叉树、二叉搜索树.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/树、二叉树、二叉搜索树.md -------------------------------------------------------------------------------- /泛型递归、树的递归.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/泛型递归、树的递归.md -------------------------------------------------------------------------------- /深度优先搜索、广度优先搜索.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cosen95/js_algorithm/c4eefce37fa2bfca710d32459dda0cecdf3ae60b/深度优先搜索、广度优先搜索.md -------------------------------------------------------------------------------- /记录.md: -------------------------------------------------------------------------------- 1 | ## 快速上手几种数据结构的概念 2 | 3 | ### 栈(`Stack`) 4 | 5 | 栈(`Stack`)——只用 `pop` 和 `push` 完成增删的“数组” 6 | 7 | 栈是一种后进先出(`LIFO`,`Last In First Out`)的数据结构。 8 | 9 | 有两个特征: 10 | 11 | - 只允许从尾部添加元素 12 | - 只允许从尾部取出元素 13 | 14 | 对应到数组的方法,刚好就是 `push` 和 `pop`。因此,我们可以认为在 `JavaScript` 中,栈就是限制只能用 `push` 来添加元素,同时只能用 `pop` 来移除元素的一种特殊的数组。 15 | 16 | 除了 `pop` 和 `push` 之外,栈相关的面试题中往往还会涉及到取`栈顶元素`的操作。所谓栈顶元素,实际上它指的就是数组尾部的元素。 17 | 18 | 下面我们基于数组来实现一波栈的常用操作: 19 | 20 | > 这里以平时“放置冰淇淋”和“卖冰淇淋”的过程为例 21 | 22 | ```js 23 | // 初始状态,栈空 24 | const stack = []; 25 | // 入栈过程 26 | stack.push("东北大板"); 27 | stack.push("可爱多"); 28 | stack.push("巧乐兹"); 29 | stack.push("冰工厂"); 30 | stack.push("光明奶砖"); 31 | 32 | // 出栈过程,栈不为空时才执行 33 | while (stack.length) { 34 | // 单纯访问栈顶元素(不出栈) 35 | const top = stack[stack.length - 1]; 36 | console.log("现在取出的冰淇淋是", top); 37 | // 将栈顶元素出栈 38 | stack.pop(); 39 | } 40 | 41 | // 栈空 42 | stack; // [] 43 | ``` 44 | 45 | ### 队列(`Queue`) 46 | 47 | 队列(`Queue`)——只用 `push` 和 `shift` 完成增删的“数组”。 48 | 49 | 队列是一种先进先出(`FIFO`,`First In First Out)的数据结构。 50 | 51 | > 它比较像咱们去肯德基排队点餐。先点餐的人先出餐,后点餐的人后出餐。 52 | 53 | 这个过程的规律也很明显: 54 | 55 | - 只允许从尾部添加元素 56 | - 只允许从头部移除元素 57 | 58 | 也就是说整个过程只涉及了数组的 `push` 和 `shift` 方法。 59 | 60 | 在栈元素入栈时,我们关心的是栈顶元素(数组的最后一个元素);队列元素出队时,我们关心的则是队头元素(数组的第一个元素)。 61 | 62 | 下面我们基于数组来实现一波队列的常用操作: 63 | 64 | ```js 65 | const queue = []; 66 | queue.push("顾客1"); 67 | queue.push("顾客2"); 68 | queue.push("顾客3"); 69 | 70 | while (queue.length) { 71 | // 单纯访问队头元素(不出队) 72 | const top = queue[0]; 73 | console.log(top, "取餐"); 74 | // 将队头元素出队 75 | queue.shift(); 76 | } 77 | 78 | // 队空 79 | queue; // [] 80 | ``` 81 | 82 | ### 链表 83 | 84 | ### 树与二叉树 85 | 86 | #### 二叉树的遍历 87 | 88 | 以一定的顺序规则,逐个访问二叉树的所有结点,这个过程就是二叉树的遍历。按照顺序规则的不同,遍历方式有以下四种: 89 | 90 | - 中序遍历 91 | - 先序遍历 92 | - 后序遍历 93 | - 层次遍历 94 | 95 | 按照实现方式的不同,遍历方式又可以分为以下两种: 96 | 97 | - 递归遍历(先、中、后序遍历) 98 | - 迭代遍历(层次遍历) 99 | 100 | 假如在保证“左子树一定先于右子树遍历”这个前提,那么遍历的可能顺序也不过三种: 101 | 102 | - 根结点 -> 左子树 -> 右子树 103 | - 左子树 -> 根结点 -> 右子树 104 | - 左子树 -> 右子树 -> 根结点 105 | 106 | 上述三个遍历顺序,就分别对应了二叉树的`先序遍历`、`中序遍历`和`后序遍历`规则。 107 | 108 | 在这三种顺序中,根结点的遍历分别被安排在了首要位置、中间位置和最后位置。 109 | 110 | 所谓的“先序”、“中序”和“后序”,“先”、“中”、“后”其实就是指根结点的遍历时机。 111 | 112 | 先序遍历: 113 | 114 | ![](https://imgkr.cn-bj.ufileos.com/e6c1926c-f533-47fc-adcd-ab0422d3e947.gif) 115 | 116 | ```js 117 | // 所有遍历函数的入参都是树的根结点对象 118 | function preorder(root) { 119 | // 递归边界,root 为空 120 | if (!root) { 121 | return; 122 | } 123 | 124 | // 输出当前遍历的结点值 125 | console.log("当前遍历的结点值是:", root.val); 126 | // 递归遍历左子树 127 | preorder(root.left); 128 | // 递归遍历右子树 129 | preorder(root.right); 130 | } 131 | ``` 132 | 133 | 中序遍历: 134 | 135 | ![](https://imgkr.cn-bj.ufileos.com/c7620e5d-d731-4739-86c6-1a54ffa71da7.gif) 136 | 137 | ```js 138 | // 所有遍历函数的入参都是树的根结点对象 139 | function inorder(root) { 140 | // 递归边界,root 为空 141 | if (!root) { 142 | return; 143 | } 144 | 145 | // 递归遍历左子树 146 | inorder(root.left); 147 | // 输出当前遍历的结点值 148 | console.log("当前遍历的结点值是:", root.val); 149 | // 递归遍历右子树 150 | inorder(root.right); 151 | } 152 | ``` 153 | 154 | 后序遍历: 155 | 156 | ![](https://imgkr.cn-bj.ufileos.com/9be11fe3-71d3-447e-a961-80bbcc621ec7.gif) 157 | 158 | ```js 159 | function postorder(root) { 160 | // 递归边界,root 为空 161 | if (!root) { 162 | return; 163 | } 164 | 165 | // 递归遍历左子树 166 | postorder(root.left); 167 | // 递归遍历右子树 168 | postorder(root.right); 169 | // 输出当前遍历的结点值 170 | console.log("当前遍历的结点值是:", root.val); 171 | } 172 | ``` 173 | 174 | ## 时间复杂度与空间复杂度 175 | -------------------------------------------------------------------------------- /题解.md: -------------------------------------------------------------------------------- 1 | 🍋 为了方便讨论,目前题解统一整理在`issues`里面:https://github.com/Jack-cool/js_algorithm/issues 2 | --------------------------------------------------------------------------------