数据结构与算法(一)
前言 为什么前端需要学习数据结构与算法
首先,算法是一个很抽象并且广发的概念,我们生活中所做的很多事情都可以说是涉及到算法。收拾房间的时候,选择先收拾哪,在收拾哪。周末选择还洗衣服还是先整理花草等等。 想把事情做好,就要在做事情之前先有所规划,而写代码也是一样。
当我们接到一个需求的时候,首先要做的就是对需求进行梳理,对需求的梳理首先就是与产品确定需求是做什么的,哪些功能是可以实现的,哪些功能是很耗时的,还有一些是耗时并且效果也尽如人意。还有一些是需要进行技术调研的。
当然对于前端很重要的还有就是交互方式,要考虑的是产品和交互想要的效果,能不能实现,会不会出现什么问题,从技术的角度来给出建议,其次就是评估时间成本。
还有些需求看起来很简单,但是实际业务场景很复杂。我们要和后台确认交互方式,哪些是接口实现的,哪些需要前端进行数据缓存,还有前置校验。复杂的交互可能会大大的占用开发联调时间,导致工时评估不准确。会造成感工期造成的加班。
最近大家应该都经历了或者听说了,经济低迷,市场行情不好,用同事的话概况就是,招人的公司80%都是外包,剩下的20%要求特别高,为什么呢?首先因为失业人群在不断的壮大,大量公司倒闭。20%的公司在吸收原来100%的人员,所以现在是甲方市场,公司当然是择优录取,首先就从学历、履历、背景来卡掉大部分人。
以前我也曾经不服气,说高中没好好学习的人,长大以后不一定就不优秀。还记得那时候的cto说,他们也知道,有些人也优秀,但是211 985 中的优秀的概率会更大。限制了门槛,节约了很多筛选的时间和成本。以前经济好的时候,我从来没有觉得自己比那些好学校的差很多,现在的现实告诉我,小时候好好学习还是很重要的。
好了,废话就说到这里吧。上面大概是我决定好好做个人的前提,计划从今天开始把数据结构和算法学习记录一遍。希望大家共勉。
本文主要是基于数据结构与算法书为原型加上自己的理解,如有不对的地方,望大家海涵。
本章节计划在半个月内更新完,每天更新一章。
第一章 数组
2.1 什么是数组,数组是特殊的对象
概念: 一个存储元素的线性集合,元素可以通过索引来任意取值,索引通常是数字,用来计算元素之间存储位置的偏移量。
首先数组不是js独有的,几乎所有的编程语言都有数组,但是js的数组与其他语言的有所不同。js的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性,索引可能是整数。因为js对象中的属性必须是字符串,所以这些索引在内部被转换成字符串类型。由于数组在js中是一种特殊对象,所以性能上没有其他语言中的高效。
2.2 数组的使用
2.2.1 创建数组
方法一 字面量方式创建
空数组 var numbers = [];
不为空的数组 var numbers = [1,2,3,4,5] console.log(numbers.length)
方法二 构造函数创建数组
var numbers = new Array(1,2,3,4,5);
只传入一个参数的时候,表示数组的长度。
var numbers = new Array(20)
js的数组,每一个值可以是不同的类型。如何判断一个对象是不是数组呢?Array.isArray()
2.2.2 读写数组
通过循环给数组赋值
var nums = [];
for(var i =0; i<100;++i) {
nums[i] = i+1;
}
console.log(nums[0])
js的数组长度是可以任意增长的,可以超出创建的长度。
2.2.3 由字符串生成数组
这里涉及到一个常用知识点,字符串转换成数组的方法。split() 那么它的工作原理是什么呢?
var sentence = "the quick brown fox jumped over the lazy cat";
var words = sentence.split(" ");
for(var i =0;i<words.lemgth;++i) {
console.log('word' + i + ":" + words[i]);
}
2.2.4 对数组的整体操作
1 整体赋值 将一个数组整体赋值给另一个数组。这里会涉及到数组是引用类型,直接赋值只是给数组增加了一个引用,改变数组两个值都会改变。这种行为是浅拷贝,新数组依然指向原来的数组。那么怎样才能实现深拷贝呢。通过循环赋值,逐项拷贝。
function copy (arr1,arr2) {
for(let i=0;i<arr1.length;++i) {
arr2[i] = arr1[i];
}
}
2.3 存取函数
概念: js提供了一组用来访问数组元素的函数,叫做存取函数,这些函数返回数据的某种变体。
2.3.1查找元素
Array.indexOf(name)如果存在返回具体位置,如果不存在返回-1 。indexOf()只返回第一个查找到的元素的位置。lastIndexOf 返回元素中最后一个相同的索引。
2.3.2 数组转换成字符串
join()和toString()
2.3.3 会生成新数组的方法
concat() 连接多个数组创建新数组。返回值为新数组
splice() 截取部分创建新数组,splice()第一个参数是开始的索引,第二个参数是截取的个数,必须是数组,可以为0,只传一个参数是从开始到数组结束的位置。还有第三个参数,第二个以后都是要添加到数组的新元素。返回值为新数组
2.4 可变函数(会直接改变原数组的方法)
2.4.1 添加元素
将一个元素添加到数组末尾 push()返回值为添加的元素
将一个元素添加到数组开头 unshift()可以一次性添加多个元素。 返回值为添加的元素
2.4.2 删除元素
从末尾删除一个元素 pop()返回值为删除的元素
从开头删除一个元素shift()返回值为删除的元素
2.4.3 为数组排序
reverse() 数组顺序翻转。字符串使用sort()会改变原数组,返回改变后的数组。
2.5 为迭代器方法
2.5.1 不生成新数组
forEach()forEach 中间不能停止,写判断符合条件后禁止是不生效的后面还会继续执行。不会改变原数组,也没有返回值。 函数没有返回值就是undefined z
every()接受返回布尔值的函数,所有为真则为真。
some() 接受布尔值函数,一个为真就为真。
reduce()接收一个函数,返回一个值,可以用来求和。还可以将数组的元素连成一个长的字符串。
reduce(add) 是数字
reduce(add)
function add (total,current) {
return total + cuttent
}
function concat (string,current) {
return string + cuttent
}
2.5.2 生成新数组
map()和forEach()类似,map返回新数组.不改变原数组
filter() 和every()类似,filter() 返回一个新数组,不改变原数组
2.6 二维和多维数组
二维数组是一种类似由行和列构成的数据表格。在js中创建二维数组,需要先创建一个数组,然后让数组中的每一个元素也是一个数组。
var twoArr = [];
var rows = 5;
for(let i=0;i<rows;++i) {
twoArr[i] = [];
}
Array.matrix = function (numrows,numcols,initial) {
var arr = [];
for(var i =0;i<numrows;++i) {
var columns = [];
for(var j =0;j<numcols;++j) {
columns[j] = initial;
}
arr[i] = columns;
}
return arr;
}
var nums = Array.matrix(5,5,0)