1. 什么是数组
- 数组是值的有序集合。
- 每个值叫做一个元素。
- 每个元素在数组中有一个位置, 以数字表示,称为索引 (有时也称为下标)。
- 数组的元素可以是任何类型。
- 数组索引从 0 开始,数组最大能容纳 4294967295 个元素。
2. 数组的声明与使用
2.1 使用字面量的方式声明数组
语法:var/let 数组名 = [元素,元素,...];
// 定义所有的姓名组成的集合
var nameList = ['小王', '小李', '张三'];
//定义由数字组成的数组
var numList = [112,232,34,34234,3434,3434,121,112,112,112];
//数组的元素各种类型都有
var list = ['张三', 100, true, false, '李四', [1, 2, 3]];
2.2 读写数组元素
1. 使用操作符 [ ] 来读写数组的每一个元素,[ ]中是数组的索引。
语法: 数组名[索引下标];
// 读取数组中元素的值
nameList[12];
// 给数组中的元素赋值
nameList[2] = 100;
2. 数组可以通过 length 属性获取数组的长度,也就是数组中元素的个数。
语法: 数组名.length;
nameList.length; // 获取数组 nameList 的长度
3. 如果数组索引超过数组的长度,数组[大于元素个数的索引] = 值;是这个写法有赋值相当于新增。如果是数组[大于元素个数的索引]这个写法是直接访问没有的索引,默认值为undefined。
var ary=[1,2,3];
ary[3]=200;//相当于新增一个
ary[5]=300;
console.log(ary);//[1, 2, 3, 200, empty, 300]
console.log(ary[4]);//undefined
4. 数组length属性的特别之处(他不是只读的,通过修改length,可以从数组末尾删除或添加元素)。
let colors=['red','blue','green'];
colors.length=2;
console.log(colors[2])//undefined
ary.length=7;//新增的元素都用undefined填充
ary[ary.length]='black';//数组最后添加一个
2.3 遍历数组(迭代)
使用 for循环或 for in 循环。
// for 循环遍历
for (var i = 0; i < arr.length; i ++) {
arr[i]
}
//for in 循环
for (var i in arr) {
arr[i]
}
2.4 多维数组
// 创建多维数组
var cityList = [
['广州', '深圳', '佛山', '东莞', '惠州'],
['南京', '苏州', '徐州', '无锡', '南通'],
['济南', '青岛', '烟台', '潍坊', '淄博'],
['杭州', '宁波', '温州', '绍兴', '湖州']
];
// 多维数组取值
cityList[2][1];
for (let i = 0; i < cityList.length; i++) {
for (let j = 0; j < cityList[i].length; j++) {
console.log(cityList[i][j]);
}
}
3. 数组方法15个
3.1 push(数据...)(后增)
-
作用:向数组末尾追加某一项。
-
参数:添加的具体项,可以是一项,也可以是多项。
-
返回值:新数组的长度。
-
是否改变原数组:改变。
var colors = ['red', 'pink'];
var res = colors.push('blue');
// 原数组
console.log(colors);//['red', 'pink', 'blue']
// 返回值
console.log(res);//3
3.2 pop()(后删)
-
作用:删除数组的最后一项。
-
参数:无。
-
返回值:删除的项。
-
是否改变原数组:改变。
var colors = ['red', 'pink'];
var res = colors.pop();
// 原数组
console.log(colors);//['red']
// 返回值
console.log(res);//'pink'
3.3 unshift(数据...)(前增)
-
作用:向数组的开头添加内容。
-
参数:添加的内容。
-
返回值:新数组的长度。
-
是否改变原数组:改变。
var colors = ['red', 'pink'];
var res = colors.unshift('blue', 'green');
// 原数组
console.log(colors);//['blue', 'green', 'red', 'pink']
// 返回值
console.log(res);//4
3.4 shift(前删)
-
作用:删除数组的第一项。
-
参数:无。
-
返回值:删除的项。
-
是否改变原数组:改变。
var colors = ['red', 'pink'];
var res = colors.shift();
// 原数组
console.log(colors);//['pink']
// 返回值
console.log(res);//red
3.5 reverse()(反排)
-
作用:把数组元素反向排列。
-
参数:无。
-
返回值:是排序后的新数组。
-
是否改变原数组:改变。
var ary=[1,2,3];
var res=ary.reverse();
console.log(res);//[3,2,1];
console.log(ary);//[3,2,1];
3.6 sort ()(排序)
-
作用:把数组进行排序。
-
参数:无或者有一个函数。
-
返回值:排序后的新数组。
-
是否改变原数组:改变。
注意!!!
如果是排序的数是多位数,sort ()不传参的时候是无法进行排序的,这时sort ()必须传参。
//----------------------不传参的时候
//=====>10 以内的可以排
var ary=[3,2,1,6,8];
ary.sort();
[1, 2, 3, 6, 8]
//=====> 超出10
var ary2=[1,21,5,33,26]
ary2.sort();
[1, 21, 26, 33, 5];
//---------------------------传参的时候
var ary2=[1,21,5,33,26]
ary2.sort(function(a,b){
return a-b; // 升序
return b-a; //降序
})
3.7 splice()(增删改一体化)
-
作用:删除/新增/修改。
-
参数:splice(n,m,...x)不能传负数。
-
返回值:删除/新增/修改的元素。
-
是否改变原数组:改变。
3.7.1 删除
- 删除需要给splice传递两个参数。
- 第一个参数:要删除的第一个元素的位置。
- 第二个参数:要删除的元素数量。
- 返回值:删除的内容放在新数组中返回。
语法: 数组名.splice(开始索引位置, 删除的个数);
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 2);
console.log(nums);// [3, 4, 5, 6]
console.log(res);// [1,2]
3.7.2 新增
新增需要传递3个参数,新增的内容在开始索引的前面。
第一个参数:开始的位置。
第二个参数:0(要删除的元素数量)。
第三个参数: 要插入的元素(任意个)。
返回值:空数组。
语法: 数组名.splice(开始索引位置, 删除的个数为0,新增的内容(可以是多个));
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(3, 0, 7, 8, 9);
console.log(nums);//[1, 2, 3, 7, 8, 9, 4, 5, 6]
console.log(res);// []
3.7.3 修改
修改也需要传递3个参数。
第一个参数:开始的位置。
第二个参数:要修改的元素数量。
第三个参数: 要插入的元素(任意个)。
返回值:修改的内容放在新数组中返回。
语法: 数组名.splice(开始索引位置, 修改的个数,修改的内容(可以是多个));
注意:修改的个数和新增的个数可以不一致。
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.splice(0, 3, 7, 8, 9);
console.log(nums);//[7, 8, 9, 4, 5, 6]
console.log(res);// [1, 2, 3]
3.8 fill()(填充)
- 作用:填充。
- 参数:有3个参数。
第一个参数:填充的内容。
第二个参数:开始索引。
第三个参数:结束索引。
- 返回值:填充后的数组。
-
是否修改原数组:改变。
注意!!!
数组.fill(内容,开始索引,结束索引) :包头不包尾。
数组.fill(内容) :从开头到结尾,就是完全替换。
数组.fill(内容,开始索引) :从开始索引到最后。
无参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill();
console.log(res);//[undefined,undefined,undefined,undefined,undefined]
console.log(arr);//[undefined,undefined,undefined,undefined,undefined]
有一个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3);
console.log(res);//[3,3,3,3,3]
console.log(arr);//[3,3,3,3,3]
有二个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3, 2);
console.log(res);//[10,20,3,3,3]
console.log(arr);//[10,20,3,3,3]
有三个参数:
let arr = [10, 20, 30, 40, 50];
let res = arr.fill(3, 0, 2);
console.log(res);//[3,3,30,40,50]
console.log(arr);//[3,3,30,40,50]
两种创建数组方法的区别:
字面量的方法,其实是添加一个内容为5,length为1。
构造函数法,其实是指定数组的length为5,内容为undefined。
注意!!!这两种创建数组方法都可以使用普通for循环进行循环。
3.9 slice(截取包前不包后)
-
作用:从原有的数组中截取特定的内容,放在新数组中,原有的数组不变。
-
参数:可以没有或有一个或者有两个。
-
返回值:返回值是截取出来的内容组成的新数组。
-
是否改变原数组:不改变。
1. 如果没有参数,slice()会返回整个数组,相当于复制数组。
语法: 数组名.slice();
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice();
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [1, 2, 3, 4, 5, 6]
2. 如果只有一个参数,slice()会返回该索引到数组末尾的所有元素。
语法: 数组名.slice(开始索引);
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5, 6]
3. 如果有两个参数,slice()返回从开始索引到结束索引对应的所有元素。
语法:数组名.slice(开始索引, 结束索引);
但是不包含结束索引 数组名.slice(n,m),包含n,不包含m
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(1, 5);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5]
4. 如果slice()的参数有负值,那么就以数组长度加上这个负数来确定位置。
长度为6,slice(-5,-1)就相当于slice(1,5)
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(-5, -1);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// [2, 3, 4, 5]
5. 如果结束位置小于开始位置,则返回空数组。
var nums = [1, 2, 3, 4, 5, 6];
var res = nums.slice(-1, -5);
console.log(nums);//[1, 2, 3, 4, 5, 6]
console.log(res);// []
3.10 concat(拼接)
-
作用:实现多个数组或者值的拼接。
-
参数:拼接的内容。
-
返回值:返回值是拼接后的新数组。
-
是否改变原数组:不改变。
语法:concat(拼接的内容);
var ary1 = [1, 2, 3];
var ary2 = [4, 5, 6];
var res = ary1.concat(ary2, "快乐", "同学");
console.log(ary1);//[1, 2, 3]
console.log(res);//[1, 2, 3, 4, 5, 6, '快乐', '同学']
3.11 toString(数组转字符串)
-
作用:可以把数组转换为字符串。
-
参数:无参。
-
返回值:返回值是转换后的字符串。
-
是否改变原数组:不改变。
-
数组中每一个元素转为字符串,然后是使用逗号连接输出显示。
语法:数组名.toString();
var ary1 = [1, { a: 1 }, null, undefined, 3];
var res = ary1.toString();
console.log(ary1);//[1, {a:1},null, undefined, 3]
console.log(res)//1,[object Object],,,3
alert方法最终体现的是字符串,会调用toString(),所以alert([1,2])结果是1,2。
3.12 join(指定连接符)
-
作用:把数组通过指定的连接符,转换为字符串。
-
参数:无参或有参(连接符)
-
返回值:返回值是转换后的字符串,无参默认使用逗号隔开,有参默认使用传入的参数内容隔开。
-
是否改变原数组:不改变
1. 无参语法: 数组名.join();
var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let newArr2 = arr.join();
console.log(newArr2)//1,2,3,4,6,7,8,9
2. 有参语法: 数组名.join("连接符"); ,自定义参数拼接。
var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let newArr3 = arr.join("|");
console.log(newArr3)//“1|2|3|4|6|7|8|9”
综合案列:
var ary1 = [1, 2, undefined, 3, { a: 1 }];
var res = ary1.join("|");
console.log(ary1);//[1, 2, undefined, 3, { a: 1 }]
console.log(res)// 1|2||3|[object Object]
eval(res) //==> eval 执行计算
3.13 indexOf/ lastIndexOf(包含,返回索引下标)
-
作用:判断数组中是否含有某一项内容,返回含有某一项内容索引下标(有多个相同内容的时候,返回第一个索引下标);不包含返回-1。
-
参数:有2个参数。
第一个参数:想要判断的内容。
第二个参数:开始索引(默认为0)。
-
返回值:-1 或者具体的索引下标
-
是否改变原数组:不改变。
1. indexOf()语法:索引从左往右开始
有一个参数的时候:
数组名.indexOf(想要判断的内容);
有二个参数的时候:
数组名.indexOf(想要判断的内容,开始索引);
2. lastIndexOf()语法:索引从右往左开始
有一个参数的时候:
数组名.lastIndexOf(想要判断的内容);
有二个参数的时候:
数组名.lastIndexOf(想要判断的内容,开始索引);
案列:
+ 作用:检测数组中的某项在数组中(首次indexOf/最后lastIndexOf)出现的位置
var ary=[1,2,3,4,1,55,1];
//检测1这个项目在数组ary 中首次出现的位置
ary.indexOf(1); //0
//从索引2开始,检测1这个项目在数组中首次出现的位置
ary.indexOf(1,2); //4
// 检测1这个项目在数组中最后一次出现的索引
ary.lastIndexOf(1);
// 检测1这个项目在数组中最后出现的索引,在索引5的位置停止检测
ary.lastIndexOf(1,5)
//如果此项在数组中没有出现,返回值就是-1
ary.indexOf(66)===>-1
3.14 includes(包含,返回布尔值)
-
作用:判断数组中是否包含某一项。
-
参数:具体内容。
-
返回值:布尔值(true,false)。
-
是否修改原数组:不改变。
var arr = [1, 2, 3, 4, 6, 7, 8, 9];
let res = arr.includes(1);
console.log(res)//true
3.15 flat(数组拍平)
-
作用:数组扁平化。
-
参数:有参 / 无参 / Infinity。
无参数默认是一层拍平。
有参就是参数是几就是几层拍平。
参数是Infinity就是不管是几层全部都拍平。
-
返回值:拍平后的数组。
-
是否修改原数组:不改变。
let arr = [1, 2, [3, 4, ["a", "b", ["A", "B", "C"]]]];
let res1 = arr.flat();
console.log(res1);//[1, 2, 3, 4,["a", "b", ["A", "B", "C"]]]
let res2 = arr.flat(2);
console.log(res2);//[1,2,3,4,"a","b",["A","B","C"]]
let res3 = arr.flat(Infinity);
console.log(res3);//[1,2,3,4,"a","b","A","B","C"]
4. 数组迭代方法9个
迭代、循环、遍历
4.1 forEach(遍历,不用return)
-
作用:遍历数组中的每一项,注意forEach中的return不起作用。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:undefined,函数没有return默认值就是undefined。
-
是否修改原数组:不改变。
注意!!!
forEach方法用来遍历数组的每一项, forEach方法没有返回值,不用加return。
语法:
数组名.forEach( (item,index,array) => {
})
案列:
let arr = [10, 20, 30];
let res = arr.forEach((item, index, arr) => {
console.log(item, index, arr);
})
console.log(res);//undefined
4.2 map(映射,用return)
-
作用:把一个数组可以映射成一个新的数组。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:映射后的新数组。
-
是否修改原数组:不改变。
语法:
数组名.map( (item,index,array) => {
return 结果;
})
案列:
// 有一个数组装着2021年所有人的年龄,2022年以后,每个人的年龄都增加1岁
var allAge = [19,15,2,30,32,43,45];
var age2020 = allAge.map(function (item,index,arr) {
return item+1;
})
console.log(age2020);//[20,16,3,31,33,44,46]
4.3 filter(过滤内容)
-
作用:过滤,把满足条件的内容都查找出来,满足条件看return。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:过滤后的新数组,没有过滤到是0。
-
是否修改原数组:不改变。
let arr = [10, 20, 30];
let res = arr.filter((item, index) => {
return item >= 30;
})
console.log(res);//[30]
console.log(arr);//[10, 20, 30]
4.4 find(查找内容)
-
作用:查找,把满足条件(return)的内容都查找出来,只要第一项。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:查找的那一项,查找不到就是undefined。
-
是否修改原数组:不改变。
let arr = [10, 20, 30];
let res = arr.find((item, index) => {
return item > 30;
})
console.log(res);//undefined
console.log(arr);//[10, 20, 30]
4.5 findIndex(查找索引)
-
作用:查找,把满足条件(return)的内容索引查找出来,只要第一项。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:查找的那项索引值,查找不到就是-1。
-
是否修改原数组:不改变。
let arr = [10, 20, 30];
let res = arr.findIndex((item, index) => {
return item > 20;
})
console.log(res);//2
4.6 some(条件为或||)
-
作用:数组中有一项满足return条件的就可以。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:布尔值(true,false)。
-
是否修改原数组:不改变。
let arr = [10, 20, 30, 40, 50];
let res = arr.some((item, index) => {
return item > 20;
})
console.log(res);//true
4.7 every(条件为与&&)
-
作用:数组中全部都满足return条件的才成立true。不成立为false。
-
参数:函数。函数有3个形参。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身。
-
返回值:布尔值(true,false)。
-
是否修改原数组:不改变。
let arr = [10, 20, 30, 40, 50];
let res = arr.every((item, index) => {
return item > 20;
})
console.log(res);//false
4.8 reduce(用作购物车求和)
-
作用:一般用于求和。
-
方向:从左到右循环,正序。
-
参数:函数。函数有4个形参。
sum : 和。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身
有传实参时,相当于给sum赋初始值,item则从该数组索引0处开始循环。如果没有传实参索引时,sum初始值默认为该数组索引0处的值,item则从该数组索引1处开始循环。
-
返回值:求的和。
-
是否修改原数组:不改变。
let arr = [10, 20, 30, 40, 50];
let res = arr.reduce((sum, item, index) => {
console.log(sum, item, index);
return sum + item;
})
console.log(res);//150
console.log(sum, item, index);解析
// sum item index
第一轮:10 20 1
第二轮:30 30 2
第三轮:60 40 3
第四轮:100 50 4
return 150
4.9 reduceRight
-
作用:一般用于求和。
-
方向:从右到左循环,倒序。
-
参数:函数。函数有4个形参。
sum : 和。
item:函数的每一项。
index:每一项的索引位置。
array:数组本身
有传实参时,相当于给sum赋初始值,item则从该数组索引0处开始循环。如果没有传实参索引时,sum初始值默认为该数组索引0处的值,item则从该数组索引1处开始循环。
-
返回值:求的和。
-
是否修改原数组:不改变。
let arr = [10, 20, 30, 40, 50];
let res = arr.reduceRight((sum, item, index) => {
console.log(sum, item, index);
return sum + item;
})
console.log(res);//150
console.log(sum, item, index);解析
// sum item index
第一轮:50 40 3
第二轮:90 30 2
第三轮:120 20 1
第四轮:140 10 0
return 150
5. 数组方法总结
5.1 会修改原来数组的方法8个
push(),pop(),shift(),unshift(),reserve(),sort(),splice(),fill()
5.2 删除数组的最后一项的方法3个
数组名.pop( )
数组名.splice( 数组名.length-1, 1)
数组名.length--
5.3 在数组尾部追加内容的方法3个
数组名.push( )
数组名.splice( 数组名.length, 0, 追加的内容)
数组名.[数组名.length] = 追加的内容;
6. 算法之数组去重
6.1 方法一:数组内部进行比较
【简单思路实现】:依次拿出数组的中的每一项,和后面的所有项进行比较,如果有相同的就删除。
思路:
第一次:
拿出数组的第一项:1
给[2,3,2,4]进行比较,如果有重复就删除
拿出数组的第二项:2
====[3,2,4]进行比较,有重复的删除 [3,4]
拿出数组的第三项:3
===4 进行比较,有重复的删除,没有重复
还用拿最后一项4吗?====不用了
依次拿出数组中的每一项给剩余的所有项进行比较
var ary=[1,2,3,2,4];
function unique(ary){
for(var i=0;i<ary.length-1;i++){
var getItem=ary[i];
for(var j=i+1;j<ary.length;j++){
var remainItem=ary[j];
// 如果当前项和后面的项在进行比较的时候,相同就说明重复,要删除掉原数组的那项
if(getItem==remainItem){
ary.splice(j,1);
j--;
}
}
}
return ary;
}
console.log(unique(ary));
【splice造成的数组塌陷问题】
var ary=[1,2,1,3,3,2,3];
for(var i=0;i<ary.length-1;i++){
var current=ary[i];
for(var j=i+1;j<ary.length;j++){
var next=ary[j];
if(current==next){
ary.splice(j,1);
j--;
}
}
}
console.log(ary)
6.2 方法二:利用对象属性名具有唯一性的特点
【实现的思路】利用对象属性名不重复的思想,先建立一个空对象,然后依次循环数组中的每一项,把此项作为obj对象的属性名和属性值,在添加的时候,如果这个属性名对应的值已经存在,说明此项重复,删除掉此项。
var ary2=[1,2,1,3,3,2,3];
利用对象属性名不能重复的原理:对象中如果没有一个属性的时候就是undefined
把数组中的每一项作为一个对象的属性名和属性值
var obj={1:1,2:2,3:3}
原理:如果对象属性中已经存在这个属性名,我们就把原数组中此项进行删除
function unique(ary){
var obj={};
for(var i=0;i<ary.length;i++){
var item=ary[i];
if(typeof (obj[item])!="undefined"){
//如果此时对象的此属性已经有了,我们就应该删除数组中的那一项
ary.splice(i,1);
i--;
continue;
}
obj[item]=item;
}
return ary;
}
var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);
【优化方法】:对于数组塌陷,数组中后面所有的数字都要依次改变,这样比较耗性能,怎么优化呢?可以让后面的索引值不变,这样就可以省性能。
-
把最后一项的值拿过来,占位到塌陷的此项
-
把最后一项删除
-
需要注意,此时最后一项也需要比较所以还需要i--;
var ary=[1,2,3,2,3];
var obj={};
for(var i=0;i<ary.length;i++){
var item=ary[i];
if(typeof obj[item]!=="undefined"){
// 把当前重复的项替换成最后一项
ary[i]=ary[ary.length-1];
// 最后一项都已经拿过来了,多余,所以删除掉
ary.length--;
// 此时占位的这一项(最后一项)还没有比较,所以需要i--,再重新比较一次
i--;
continue;
}
obj[item]=item;
}
console.log(ary);
6.3 方法三:indexOf
【实现思路】创建一个新数组,遍历原数组,如果新数组中没有那一项的话,就把它push进去。
var ary2=[1,2,1,3,3,2,3];
var newAry=[];
把原数组中的每一项,只要在新数组中没存在过,我们就把它放进去,最后newAry就是咱们最终要的数组。
function unique(ary){
var newAry=[];
for(var i=0;i<ary.length;i++){
var item=ary[i];
if(newAry.indexOf(item)==-1){
newAry.push(item);
}
}
return newAry;
}
var ary2=[1,2,1,3,3,2,3];
var res=unique(ary2);
console.log(res);
7. 算法之冒泡排序
冒泡排序:
从小到大排序
var ary=[8,2,1,5]
原理:依次拿出数组中的每一项给后面的一项做对比,如果当前项比后面的项大就交换位置
第一轮:[2,1,5,8] 经过一轮比较出现了最大数
第二轮:[1,2,5,8] 经过二轮比较得出倒数第2个数
第三轮:[1,5,2,8] 经过二轮比较得出倒数第3个数
.... 总共四项,经过比三轮,已经得到了三个最大数了,最后一个自然就是最小数
【需要比的总轮数】:ary.length-1;
【每次需要比的次数】:ary.length-1-已经比较过的轮数第一轮:4项两两比较需要比3次:ary.length-1
第二轮: 正常的ary.length-1-已经比较过的轮数
function sort(ary){
// 需要比较的轮数
for(var i=0;i<ary.length-1;i++){
for(var j=0;j<ary.length-1-i;j++){
var current=ary[j];
var next=ary[j+1];
if(ary[j]>ary[j+1]){
// 让 ary[j]=ary[j+1]
var temp=ary[j]
ary[j]=ary[j+1];
ary[j+1]=temp;
}
}
}
return ary;
}
var ary=[8,2,1,5];
var res=sort(ary);
es6解构赋值
//传统的交换两个数的位置的方法
let a = 10;
let b = 20;
let c;
c = a;
a = b;
b = c;
console.log(a, b);//a=20;b=10
// es6新增方法:解构赋值
let a = 10;
let b = 20;
[a, b] = [b, a];
console.log(a, b);//a=20;b=10
8. 算法之递归
函数自己调自己就是递归
function fn(num){
fn(num-1)
}
fn(10)
练习:打印1 到10
// 打印1到10
function fn(num){
if(num>10){
return
}
console.log(num);
fn(num+1);
}
fn(1)
9. 递归练习题
9.1 求一个1到100的所有数之和
9.1.1 答案一:普通方法
/*
1到100中所有数之和
*/
function total(star,end){
var total=0;
for(var i=star;i<=end;i++){
total+=i;
}
return total;
}
var res=total(1,100);
console.log(res);
9.1.2 答案二:递归
function total(num){
if(num>100){
return 0;
}
return num + total(num+1);
}
total(1)
9.2 [练习题]:求1到100中同时能被2整除又能被3整除的所有数之和
9.2.1 答案一:普通方法
/*
求1-100所有能被2整除又能被3整除的所有数之和
*/
var total=0;
for(var i=1;i<=100;i++){
if(i%2==0&&i%3==0){
total+=i;
}
}
console.log(total);
9.2.2 答案二:递归
function total(num){
if(num>100){
return 0;
}
if(num%2==0&&num%3==0){
return num+total(num+1);
}
return total(num+1);
}
var res=total(1);
10. 算法之快速排序
快速排序:
var ary=[12,15,14,13,16,11];
原理:先拿出中间项,然后把此项从数组中删除掉,让数组中的剩余项一一跟这个中间项做比较,新建两个左右数组,如果大的项就放到右盒子,如果小的项就放到左盒子。
[左盒子小]--中间项--[右盒子大]
依次再继续重复相同的步骤,把左盒子和右盒子都进行排序,直到出现空数组或者一项的时候停止
function quickSort(ary){
if(ary.length<=1){
return ary;
}
var centerIndex=Math.floor(ary.length/2);
// 拿到中间项的同时,把中间项从数组中删除掉
var centerValue=ary.splice(centerIndex,1)[0];
// 新建两个数组:leftAry,rightAry;把ary中剩余的项,给中间项做对比,如果大项就放到右数组,小项就放到左数组.
var leftAry=[],rightAry=[];
for(var i=0;i<ary.length;i++){
if(ary[i]<centerValue){
leftAry.push(ary[i]);
}else{
rightAry.push(ary[i]);
}
}
return quickSort(leftAry).concat(centerValue,quickSort(rightAry));
}
var ary=[12,15,14,13,16,11];
var res=quickSort(ary);
11. 算法之插入排序
var ary=[34,56,12,66,12];
插入排序:
新建一个数组:依次拿出原数组中的每一项往新数组里面插入,插入的时候需要遵循一个规律:
1)方向:从右向左
2)最终实现的效果,从小到大,在插入的时候,拿出的项
从右向左依次比较(新数组),如果拿出的项大(或者相等),就直接插入首次比它小的后面,
3)如果一直比到第一项了,条件还没满足,后面就是最小项,直接放到数组的最前面
var newAry=[]
第一次====>我拿出第一项直接放进去,不用进行比较
newAry=[34]
第二次====> 拿出56 [34,56]第三次====> 拿出12 [12,34,56]
第四次=====> 拿出66 [12,34,56,66]
第五次=====> 拿出12 [12,12,34,56,66]
var ary=[34,56,12,66,12];
function insertSort(ary){
//最终排序好的数组盒子
var newAry=[];
//拿出的第一项放进去,此时盒子中只有一项,不用个比较
newAry.push(ary[0]);
// 依次拿出原数组中的每一项进行插入
for(var i=1;i<ary.length;i++){
var getItem=ary[i];
// 在插入的时候需要跟新数组中的每一项进行比较(从右向左)
for(var j=newAry.length-1;j>=0;j--){
var newItemAry=newAry[j];
if(getItem>=newItemAry){
// 如果拿出的项比某项大或者相等,就放到此项的后面
newAry.splice(j+1,0,getItem);
// 插入完毕,不用再继续比较停止循环;
break;
}
if(j==0){
//如果都已经比到第一项了,还没满足条件,说明这个就是最小项,我们之间插入到数组的最前面
newAry.unshift(getItem);
}
}
}
return newAry;
}
var res=insertSort(ary)