![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法与数据结构
秃头的科比
希望大家多关注 我会在以后的工作生活中不断的去完善文章中的不足之处
展开
-
算法——希尔排序
希尔排序希尔排序是插入排序的一种高效的改进版,并且效率比插入排序要更快,因为它突破了时间复杂度为O(n^2的限制)。由于希尔排序是基于插入排序的,所以有必要回顾一下插入排序:插入排序的问题:1,假设一个很小的数据项在很靠近右端的位置上,这里本来应该是较大的数据项的位置。2,把这个小数据项移动到左边的正确位置,那么所有的中间数据项都必须向右移动一位。3,因此我们通常认为插入排序的时间复杂度为O(n^2)。4,如果有某种方式,不需要一个个移动所有中间的数据项,就能把较小的数据项移动到左边,那么这个算原创 2022-03-09 10:59:43 · 713 阅读 · 0 评论 -
插入排序(insertionSort)
插入排序插入排序是简单排序中效率最好的一种,它也是学习其他高级排序的基础,比如希尔排序/快速排序,所以非常重要,而它相对于选择排序的优点就在于比较次数几乎是少了一半。插入排序的思路:(1)从第一个元素开始,该元素可以认为已经被排序。(2)取出下一个元素,在已经排序的元素序列中从后向前扫描。(3)如果该元素(已排序)大于新元素,则将该元素移动到下一个位置。(4)重复上一个步骤,直到找到已排序的元素小于或者等于新元素的位置,将新元素插入到该位置后,重复上面的步骤。如图所示:function i原创 2022-03-04 09:50:18 · 8869 阅读 · 12 评论 -
算法——冒泡排序
冒泡排序的思路:(1)比较所有相邻元素,如果第一个比第二个大,则交换它们。(2)一轮下来,可以保证最后一个数是最大的。(3)执行n-1轮,就可以完成排序。Array.prototype.bubbleSort = function () { for (let i = 0; i < this.length - 1; i += 1) { for (let j = 0; j < this.length - 1 - i; j += 1) { if (原创 2021-07-20 17:50:09 · 47 阅读 · 0 评论 -
算法设计思想——回溯算法
回溯算法是算法设计中的一种方法,是一种渐进式寻找并构建问题解决方式的策略,它会从一个可能的动作开始解决问题,如果不行,就回溯并选择另一个动作,直到将问题解决 。leetcode 46 全排列/** * 解题思路: * (1)所有排列;没有重复元素。 * (2)有出路,有死路。 * * 解题步骤: * (1)使用递归模拟出所有的情况 * (2)遇到包含重复元素的情况,就回溯 * (3)收集所有到达递归终点的情况并返回 */var permute = function (num原创 2021-07-20 09:23:50 · 210 阅读 · 0 评论 -
算法设计思想——贪心算法
贪心算法贪心算法是算法设计中的一种方法,期盼通过每个阶段的局部最优选择,从而达到全局的最优,但结果并不一定是最优的。leetcode 455 分发饼干/** * 解题思路: * (1)局部最优:既能满足孩子,还消耗最少 * (2)因此先将‘较小的饼干’分给‘胃口最小的孩子’ * * 解题步骤: * (1)对饼干数组和胃口数组进行升序排序 * (2)遍历饼干数组,找到能满足第一个孩子的饼干 * (3)然后继续遍历饼干数组,找到满足第二、三、····、n个孩子的饼干 */原创 2021-07-19 22:36:26 · 328 阅读 · 0 评论 -
算法设计思想——动态规划
动态规划动态规划是算法设计中的一种方法,它将一个问题分解为相互重叠的子问题,通过反复求解子问题,来解决原来的问题。它与分而治之思想的区别主要在于子问题是否是重叠的,如果子问题是相互独立的那么便使用分而治之,如果子问题是相互重叠的那么便使用动态规划。leetcode 70 爬楼梯/** * 解题思路:爬到第n阶可以在第n-1阶爬1个台阶或者在第n-2阶爬2个台阶,所以我们可以定义这样一个子问题:F(n) = F(n - 1) + F(n - 2); * 解题步骤: * (1)定义子问题:F(n)原创 2021-07-19 11:11:18 · 154 阅读 · 0 评论 -
算法设计思想——分而治之
分而治之分而治之是算法设计中的一种方法,它将一个问题分成多个和原问题相似的小问题,递归解决小问题,再将结果合并以解决原来的问题。 应用场景:归并排序、快速排序。leetcode:374 猜数字大小/** * 解题思路:二分搜索同样具备“分、解、合”的特性。这里我们考虑使用分而治之的思想。 * 解题步骤: * 分:计算中间元素,分割数组。 * 解:递归的在较大或者较小子数组进行二分搜索。 */var guessNumber = function(n) { const mainC原创 2021-07-19 09:44:48 · 439 阅读 · 0 评论 -
快速排序
快速排序思路: (1)分区:从数组中任意选择一个基准,所有比基准小的元素放在基准前面,比基准大的元素放在基准的后面。 (2)递归:递归的对基准前后的子数组进行再分区。Array.prototype.quickSort = function () { const rec = (arr) => { if (arr.length === 1) { return arr; } const left = [];原创 2021-04-12 20:30:08 · 43 阅读 · 0 评论 -
顺序搜索
顺序搜索思路:(1)遍历数组。(2)找到跟目标值相等的元素,就返回它的下标。(3)遍历结束后,如果没有搜索到目标值,就返回-1。Array.prototype.mySearch = function (a) { for (let i = 0; i < this.length; i++) { if (this[i] === a) { return i; } } return -1;};const arr =原创 2021-04-12 17:49:32 · 58 阅读 · 0 评论 -
二分搜索
二分搜索前提条件:有序数组。思路:(1)二分搜索的前提条件是有序数组,否则要先进行排序。(2)从数组的中间元素开始,如果中间元素正好是目标值,则搜索结束。(3)如果目标值大于或者小于中间元素,则在大于或小于中间元素的那一半数组中搜索。(4)重复二三步骤。/** * 二分搜索的思路: * 必须为有序数组,否则首先需要进行排序 * 从数组中的中间元素开始,如果正好为目标值,则搜索结束 * 如果目标值大于或者小于中间元素,则在大于或者小于的那一半数组元素中去进行原创 2021-04-12 17:40:45 · 145 阅读 · 0 评论 -
图
图基本概念:(1)图是网络结构的抽象模型,是一组由边连接的节点。(2)图可以表示任何二元关系,比如:道路、航班·······(3)js中没有图,但是可以使用Object和Array构建图。(4)图的表示法:邻接矩阵、邻接表、关联矩阵····图的常用操作:(1)深度优先遍历:尽可能深的搜索图的分支。(2)广度优先遍历:先访问距离根节点最近的节点。深度优先遍历算法口诀:(1)先访问根节点。(2)然后对根节点的没访问过的相邻节点挨个进行深度优先遍历。const graph = {原创 2021-04-12 12:44:18 · 57 阅读 · 0 评论 -
树
树树的基本概念: (1)一种分层数据的抽象模型。 (2)前端工作中常见的树包括:DOM树、级联选择、树形控件等等。 (3)js中没有树,但是可以用Object和Array构建树。树的常用操作:深度/广度优先遍历、先中后序遍历。深度/广度优先遍历的基本概念: (1)深度优先遍历:尽可能深的搜索树的分支。 (2)广度优先遍历:先访问距离根节点最近的节点。深度优先遍历算法口诀: 先访问根节点。 然后对根节点的children节点挨个进行深度优先遍历。深度优先遍历代码实现:(递原创 2021-04-08 22:21:37 · 123 阅读 · 0 评论 -
字典
字典基本概念:与集合类似,字典也是一种存储唯一值的数据结构,但它是以键值对的形式来存储。(ES6中有字典,Map)常用操作:键值对的增删改查。//键值对的增删改查const m = new Map();//增加m.set('a', 'aa');m.set('b', 'bb')console.log(m);//查m.get('a');//删除m.delete('a');//改(再次覆盖就行)m.set('b', 'ccc');console.log(m)练习一:lee原创 2021-04-07 21:04:22 · 48 阅读 · 0 评论 -
集合
集合基本概念:一种无序且唯一的数据结构(ES6中有名为Set的集合)。常用操作:去重、判断某个元素是否在集合中、求交集等等。代码实现://数组去重const arr = [1, 2, 2];const arr2 = [...new Set(arr)];console.log(arr2);//判断某个元素是否在集合中 const set = new Set(arr);const res = set.has(1);console.log(res);//求交集const set2 =原创 2021-04-07 20:08:31 · 61 阅读 · 0 评论 -
队列
队列基本概念:一种先进先出的数据结构。js中没有队列,但是可以使用Array实现队列的所有功能。模拟实现队列:const queue = [];queue.push(1);queue.shift();原创 2021-04-07 16:52:49 · 66 阅读 · 0 评论 -
栈
栈基本概念:一种先进后出的数据结构。js中并没有栈,但是可以使用Array实现栈的所有功能。模拟实现栈:const stack = [];stack.push(2);stack.pop();练习一:leetcode 20 有效的括号/** * 解题步骤: * 新建一个栈,扫描字符串,遇到左括号便入栈,遇到和栈顶括号类型匹配的右括号就出栈, * 类型不匹配直接判定为不合法。 */if (s.length % 2 === 1) { return false;}c原创 2021-04-07 16:50:42 · 54 阅读 · 0 评论 -
链表
链表基本概念: 多个元素组成的列表。 元素存储不连续,用next指针连在一起。链表与数组的区别: 数组:增删非首尾元素时往往需要移动元素。 链表:增删非首尾元素,不需要移动元素,只需要更改next的指向即可。不过js中是没有链表这种数据结构的,但是我们可以使用object来模拟链表。模拟实现链表://模拟创建链表const a = { val: 'a' };const b = { val: 'b' };const c = { val: 'c' };const d = {原创 2021-04-07 16:44:23 · 45 阅读 · 0 评论 -
算法复杂度
复杂度计算时间复杂度大O符号表示法并不是用于来真实代表算法的执行时间的,它只是用来表示代码执行时间的增长变化趋势的。时间复杂度常用的有:O(1)、O(log n)、O(n)、O(nlogn)、O(n^2)。常数阶O(1)无论代码执行了多少行,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1),如:int i = 1;int j = 2;++i;j++;int m = i + j;上述代码在执行的时候,它消耗的时候并不随着某个变量的增长而增长,那么无论这类代码有多长,即使有原创 2021-04-01 21:15:02 · 71 阅读 · 0 评论