数组
数据结构
概述
数据结构是一个基础的学科知识,主要讲述的是数据的结构(主要分为存储结构和逻辑结构)。算法是属于数据结构的一部分。
数据结构分类
- 存储结构 (存储数据的方式)
- 逻辑结构 (对应的存储的逻辑)
数组
概述
数组是一个基础的数据结构,它主要是一个线性的结构(有序),它使用对应的下标来进行元素的访问。
数组的声明
字面量声明
//字面量赋值
var arr = [] //数组
var arr = [1,2,3,4] //存储4个元素 分别为1,2,3,4
new关键词声明
//使用new关键词声明
//不传参 构建空数组
var arr = new Array() //[]
console.log(arr)
//传一个参数 指定对应的数组内的元素个数
var arr = new Array(5) //[empty,empty,empty,empty,empty]
console.log(arr)
//传多个参数 将参数放入到数组内
var arr = new Array(1,2,5)//[1,2,5]
console.log(arr)
数组内元素的访问
通过下标来进行访问 [下标] (下标从0开始)
var arr = ['a','b','c']
console.log(arr[1])//b
length属性 读取数组的长度
var arr = ['a','b','c']
console.log(arr.length) //3
注意事项
- length属性可以改变 (当前你的length属性修改为大于当前的length的值 它会开辟对应的空间 并赋值为empty 当你的length小于当前的length 它会从前到后截取对应的数组)
- 可以给不存在的下标进行赋值操作 (自动开辟新的空间)
数组元素的遍历
使用for循环遍历
var arr = ['a','b','c','d']
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
使用for of遍历 (ES6新增)
var arr = ['a','b','c','d']
//当前v在arr中 遍历的是值
for(var v of arr){
console.log(v)
}
使用for in遍历 (ES5新增)
var arr = ['a','b','c','d']
//当前的key在arr中 key就是对应的下标 默认从0开始到length-1结束
for(var key in arr){
console.log(arr[key])
}
练习
计算数组所有元素的和 [1,2,5,8,9]
//封装方法
function getArraySum(arr){
var sum = 0
//遍历
for(var v of arr){
sum += v
}
return sum
}
getArraySum([1,2,5,8,9])
找到数组内最大的值和最小的值交换位置 [2,5,41,6,3,1,5]
//找到数组内最大的值和最小的值交换位置 [2,5,41,6,3,1,5]
function resveArrayToMaxAndMin(arr) {
//默认取第一个下标 记录下标
var max = 0
var min = 0
//遍历 与其他的进行比较
for (var i = 1; i < arr.length; i++) {
//如果比最大值还大 那么就赋值给对应的最大值下标
if (arr[max] < arr[i]) {
max = i
}
//如果比最小值还小 那么就赋值给对应的最小值下标
if (arr[min] > arr[i]) {
min = i
}
}
//位置交换
if (max != min) {
//使用第三方的变量接收一个值
var temp = arr[max]
arr[max] = arr[min]
arr[min] = temp
}
//返回交换完的数组
return arr
}
找到数组内第二大的值 [10,15,20,5,8]
//找到数组内第二大的值 [10,15,20,20,5,8]
function getScondToArr(arr) {
//记录下标
var max = 0
//第二大的值
var scond = -Infinity
//遍历取最大值
for (var i in arr) {
if (arr[i] > arr[max]) {
//记录下标
max = i
}
}
for (var i in arr) {
//排除最大的下标
if (i != max) {
//如果你小于最大的值 大于第二大的值 那么第二大的值就是它
if (arr[i] <= arr[max] && arr[i] > scond) {
scond = arr[i]
}
}
}
console.log(scond)
}
getScondToArr([10, 15, 20,20, 5, 8])
数组的方法
所有能存储数据的容器都具备对应的增删改查方法
添加的方法 (add push set ...)
返回的新的长度 (添加后的长度 length)
push (栈方法) 添加到后面
var arr = [1,2,3]
//添加到后面
console.log(arr.push('a')) //4 添加后的数组长度
console.log(arr) //[1,2,3,'a']
unshift (队列方法)
//unshift 返回值为添加后的长度 会影响原本的数组
var arr = [1, 2, 3]
//插入到前面
console.log(arr.unshift(3,4,5,6)) //7
console.log(arr)
删除的方法 (remove delete..)
返回被删除的值
pop 删除最后一个的元素
var arr = [1,2,3]
console.log(arr.pop()) //3
console.log(arr) //[1,2]
shift 删除第一个的元素
var arr = [1,2,3]
console.log(arr.shift()) //1
console.log(arr) //[2,3]
splice 删除
//可以完成对应的删除 也 可以完成对应的修改 也可以完成对应的插入
//开始的位置 删除的数量(? 可不传) 插入的内容 (? 可不传)
//只传一个参数
console.log(arr.splice(1)) //删除到末尾
console.log(arr)
//传俩个参数
var arr = [1,2,3]
arr.splice(0,1) //从下标0开始删除1个删除对应的第一个
console.log(arr)
//传三个参数
//替换操作
var arr = [1,2,3]
arr.splice(0,2,'a','b')
console.log(arr)
//添加操作
var arr = [1,2,3]
arr.splice(2,0,'a','b')
console.log(arr)
//传入对应的负值
var arr = [1,2,3,4,5]
arr.splice(-2)
console.log(arr)
修改(replace set...)
采用元素重新赋值的方式进行修改
var arr = [1,2,3]
arr[1] = 5
查询
通过值获取下标 , 找到了返回第一个找到的下标 没有找到返回-1
indexOf (从前向后找)
var arr = ['a','a',2,3]
console.log(arr.indexOf('a')) //0
console.log(arr.indexOf(4)) //-1
//指定从对应的下标位开始找
console.log(arr.indexOf('a',1)) //1
lastIndexOf (从后往前找)
//lastIndexOf 从后往前找
var arr = ['a', 'a', 2, 3,'a']
console.log(arr.lastIndexOf('a')) //4
console.log(arr.lastIndexOf(4)) //-1
//指定从对应的下标位开始找
console.log(arr.lastIndexOf('a', 1)) //1
//-2相当于length-2
console.log(arr.lastIndexOf('a',-2)) //1
手动实现indexOf
var arr = [1,2,3,4]
//第一个参数查找的值 第二个参数为对应的位置
function myIndexOf(value,start){
//判断是否传入value
if(typeof value == "undefined"){
throw new Error('参数缺少')
}
//如果没有传入对应的start 那么默认为0
if(!start){
start = 0
}
//如果传入的start位置值为负值
if(start<0){
start = arr.length + start
}
//开始查找
//遍历进行值的比对 从start开始进行比对
for(var i=start;i<arr.length;i++){
//找到对应的值
if(value === arr[i]){
//返回下标
return i
}
}
//没有找到返回-1
return -1
}
以上的方法都会影响对应的数组本身
不影响数组本身的方法 (返回值)
concat 连接 返回一个新的数组
//concat方法
var arr = [1, 2, 3]
//连接对应的数组形成一个新的数组 concat支持传入数组及对应的值 支持多个参数
var concatArr = arr.concat([4, 5, 6],7) //连接返回新的数组
console.log(concatArr, arr) //[1,2,3,4,5,6,7] [1,2,3]
join 转为字符串
//join方法
var arr = ['a','b','c']
//传入对应的分隔符 默认情况下使用,分隔
var str = arr.join()
console.log(str,arr) //a,b,c ['a','b','c']
//以传入&符号进行分隔
var str = arr.join('&')
console.log(str,arr) //a&b&c ['a','b','c']
slice 截取返回一个新的数组
var arr = [1,2,3,4]
//传入一个参数 从下标1开始 截取到末尾
var sliceArr = arr.slice(1)
console.log(sliceArr)//[2,3,4]
//传入俩个参数 开始的位置下标 结束的位置下标(不包含)
var sliceArr = arr.slice(1,3)
console.log(sliceArr)//[2,3]
位置变换的方法
reverse 反转
var arr = [1,2,3]
//反转操作 影响原本的数组 返回值就是原本的数组
var newArr = arr.reverse()
console.log(newArr === arr) //true
console.log(arr) //[3,2,1]
sort 排序
//sort 排序方法 返回值就是原本的数组
var arr = [12,21,3,102]
arr.sort() //默认以ascii进行排序 从小到大
console.log(arr) //[102,12,21,3]
//定义排序规则
arr.sort(function(a,b){
//排序规则定义 a b表示的其中的俩个值
return a - b //a-b就正序 b-a就逆序
})
console.log(arr) //[3,12,21,102]
排序算法
基础的排序算法主要有
- 冒泡排序
- 选择排序
- 插入排序 (插入数据的时候运用的排序)
- 快速排序 (冒泡排序的升级版)
- 希尔排序 (快速插入排序)
- 归并排序 (大数据最快的排序)
- 基数排序
- 堆排序
- 桶排序
- .....
冒泡排序(On^2)
相邻俩俩相比 不断的向上冒泡
function bubbleSort(arr) {
//比较轮数
for (var i = 0; i < arr.length - 1; i++) {
//比较次数
for (var j = 0; j < arr.length - 1 - i; j++) {
//每次比较都换位置
if (arr[j] > arr[j + 1]) {
var temp = arr[j]
arr[j] = arr[j + 1]
arr[j + 1] = temp
}
}
}
return arr
}
选择排序 (On^2)
选择一个数跟其他数进行比较 然后逐一选择逐一比较
function selectorSort(arr){
//比较轮数
for(var i=0;i<arr.length-1;i++){
//认为自身最大
var max = i
//用当前这个max跟其他的进行比较
for(var j=i+1;j<arr.length;j++){
//如果比最大值还大 那么记录这个下标为最大
if(arr[max]<arr[j]){
max = j
}
}
//比较完判断当前max是否我开始设置的max
if(max!=i){
var temp = arr[max]
arr[max] = arr[i]
arr[i] = temp
}
}
return arr
}
快速排序(OnLogn)
二分法不断二分一直比较
function quickSort(arr){
//如果这个数组里面没有内容或只有一个值
if(arr.length<=1){
return arr //返回原本数组
}
//取中间值 默认为第一个
var min = arr[0]
//定义左右的数组
var left = [],right = []
//遍历数据进行比较
for(var i=1;i<arr.length;i++){
//如果比中间小放左边 如果比中间值大放右边
arr[i]>min?right.push(arr[i]):left.push(arr[i])
}
return quickSort(left).concat(min,quickSort(right))
}