数据结构
存储结构 (存储对应的数据)
- 顺序存储结构
- 链式存储结构
- 索引存储结构
- 散列存储结构
逻辑结构 (逻辑的体现)
线性结构(有顺序)
- 数组(顺序表)
- 栈 (先进后出)
- 队列 (先进先出)
非线性结构 (没有顺序)
- 串
- 链表 (单向链表 双向链表)
- 图 (有向图 无向图)
- 树 (二叉树)
- hash (哈希树)
- 所有存储结构 必须具备增删查改的方法
数组
概述:
数组是一种线性的数据结构,它里面存储的数据都是有顺序的(又称为顺序表),一般通过对应的索引下标进行访问数据,它里面存储的数据一般情况下是单一类型的数据。但是也可以存储多种数据类型。数组是存储数据的一个简易容器。
数组的定义(引用数据类型)
使用[]来声明
var arr = []
//数组也是一个对象
console.log(arr)
//[]!=[]
console.log([]==[])//false
//初始数据传入定义
var arr = [1,2,3]
console.log(arr)
使用new Array来声明
//第二种 使用 new Array的方式来定义
//无参定义
var arr = new Array()
console.log(arr)
//使用一个参数来定义
var arr = new Array(10)//这个数组里有十个值 empty
console.log(arr)
//使用多个参数
var arr =new Array(1,2,3)//这个数组里有三个值 1,2,3
console.log(arr)
数组的特性
下标 从0开始到length-1 可以通过[下标]来访问对应的数组里面的值
length长度 为数组里面值的个数 length重新修改是可行的 改大扩容 改小删除
数组的遍历
传统for循环遍历
var arr = [1,2,3]
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
for in遍历 (一般用于遍历对象 也可遍历数组)
//es5新增的 forin 循环 for in 循环是为了遍历对象 数组也是一个对象
//forin遍历的是下标 相当于对象的key
for( var index in arr){
console.log(index)//遍历的是下标
console.log(arr[index])
}
for of 遍历 (用于遍历数组不能遍历对象)
//es6新增 forof 在for in 的基础上进行改版 只能遍历数组(伪数组)
//for of 不能遍历对象
for (var value of arr){
console.log(value)//遍历的是值
}
数组遍历
示例:
var arr = [1,2,3]
for(var i=0;i<arr.length;i++){
console.log(arr[i])
}
//es5新增的 forin 循环 for in 循环是为了遍历对象 数组也是一个对象
//forin遍历的是下标 相当于对象的key
for( var index in arr){
console.log(index)//遍历的是下标
console.log(arr[index])
}
//es6新增 forof 在for in 的基础上进行改版 只能遍历数组(伪数组)
//for of 不能遍历对象
for (var value of arr){
console.log(value)//遍历的是值
}
//将一个数组的第二个元素和第三个元素进行互换位置
var arr = [1,2,3,4,5]
function fn(pos1,pos2,arr){
var change = arr[pos1-1]
arr[pos1-1] = arr[pos2-1]
arr[pos2-1] = change
}
fn(2,3,arr)
console.log(arr)
// 将数组[2,3,1,5,6,7,3]中的最大最小值进行调换
var arr = [2,3,1,5,6,7,3]
function fn1(max,min,arr){
Math.max(arr[max-1])
Math.min(arr[min-1])
var change =arr[max-1]
arr[max-1] = arr[min-1]
arr[min-1] = change
}
fn(3,6,arr)
console.log(arr)
function fn2(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
}
}
var change =arr[min]
arr[min] = arr[max]
arr[max] = change
return arr
}
console.log(fn2([2,3,1,5,6,7,3] ))
//找到数组中第二大的数
function fn3(arr){
if(arr.length<2){
return arr[0]
}
//假设 得到第一大 和 第二大的值
var max = arr[0]>arr[1]?arr[0]:arr[1]//需要值而不是下标
var sec = arr[0]<arr[1]?arr[0]:arr[1]
//进行比对
for(var i =2;i<arr.length;i++){
//如果比最大值大 就赋给最大值 把最大值先给第二大
if(max<arr[i]){
sec = max
max = arr[i]
}else{
//判断还有没有比第二大 大的值
if(sec<arr[i]){
sec=arr[i]
}
}
}
return sec
}
console.log(fn3([2,3,9,5,4,7,3] ))
数组的相关方法
- pop 删除最后一个 arr.pop()
- push 添加最后一个arr.push()
- shift 删除第一个 arr.shift()
- unshift 添加第一个 arr.unshift()
- splice 的删除操作先删再加 从下标一开始删除 包含下标 arr.splice()
不会影响原数组
- slice
- join
- concat
- indexOf根据对应的值查询下标(有就返回下标 没有就返回-1)
- lastIndexOf 从后往前查找 找到第一个 没有返回-1
示例:
//pop 删除最后一个
var arr = [1,2,3]
arr.pop()
console.log(arr)
//push
//shift
//unshift
//splice 的删除操作
//先删再加
var arr =[1,2,3]
//从下标为一的地方开始删一个 加4,5
arr.splice(1,1,4,5)
console.log(arr)//(4) [1, 4, 5, 3]
//splice 的删除操作
var arr = [1,2,3,4,5]
arr.splice(1)//省略个数删到最后 包含下标1
console.log(arr)//[1]
var arr = [1,2,3,4]
arr.splice(1,2)//从下标一开始删除两个 包含下标 1
console.log(arr)//(2) [1, 4]
var arr=[1,2,3,4]
arr.splice(2,0,5,6)//二号位为0不删 从前面写的位置添加
console.log(arr)//(6) [1, 2, 5, 6, 3, 4]
// indexOf 查找坐标(从左到右)
var arr = [1,2,4,3,4,5]
function myIndexOf(value,start){
if(value==undefined ){
throw new Error('参数未传递')
}
if(start == undefined){
start = 0//传递从第一个下标 0 开始
}else if(typeof start != 'number'){
console.log('参数类型不对')
}
//开始查询
for(var i=start;i<arr.length;i++){
if(arr[i]==value){
return i
}
}
return -1
}
console.log(myIndexOf(4))
//lastIndexOf
var arr = [1,2,4,3,4,5,7,3]
function myLastIndexOf(value,end){
if(value==undefined){
throw new Error('参数未传递')
}
if(end == undefined){
end = arr.length
}else if(typeof end != 'number'){
console.log('参数类型不对')
}
//开始查询
for(var i=end;i>=0;i--){
if(arr[i]==value){
return i
}
}
return -1
}
console.log(myLastIndexOf(4))
不影响原本数组的排序方法
- concat方法 (将数组或值拼接)
- slice 截取
- join 能使用传入的参数分割数组 不传参默认用, 分割
- sort排序的方法 默认按照ACSII码的排序方法
- reverse反转排序
var arr1= [1,2]
var arr2 = [3,4]
//数组的concat方法传入的参数为数组
var concatArr =arr1.concat(arr2)
console.log(arr1)//[1,2]
console.log(arr2)//[3,4]
console.log(concatArr)//[1,2,3,4]
var arr = [1,2,3,4,5,6]
//可以传入数组 也可以传入对应的值
var concatArr=arr1.concat(3,4)
console.log(concatArr)//[1,2,3,4]
//传入一个开始下标 结束下标(默认没有传入结束的下标将截取到最后) 不包含结束的下标
var sliceArr = arr.slice(4,5) //[5] 从下标4开始截取
console.log(sliceArr,arr)
var arr = [1,2,3,4,5]
//jion如果不传参 默认使用,来分割元素 如果传入参数 使用参数分割元素
var str = arr.join('a')//传入的参数一定是字符串
console.log(str)
//排序的相关方法
var arr = [2,3,5,10,4,6]
//默认情况下 sort方法是按照ASCII码排序
// arr.sort
// 高阶函数用法 将函数作为参数的函数叫做高阶函数
var newArr=arr.sort(function(a,b){
return a-b //正序 倒序就是 b-a
})
console.log(arr)
console.log(newArr)
//反转方法
var arr1 =arr.reverse()
console.log(arr)
console.log(arr1 == arr)
排序算法
冒泡排序
选择排序
插入排序
希尔排序
快速排序
归并排序
// 冒泡排序
// 前一个跟后一个比 比较
function bubleSort(arr){
//轮数
for(var i =0;i<arr.length-1;i++){
//对换的次数
for(var j=1;j<arr.length-i;j++){
if(arr[j]<arr[j-1]){
var temp = arr[j]
arr[j] =arr[j-1]
arr[j-1] = temp
}
}
}
return arr
}
console.log(bubleSort([7,10,2,5,1,3,98,45,34,12]))
// 选择排序
function choiceSort(arr){
for(var i=0;i<arr.length-1;i++){
//指定max为当前遍历的下标
var max=i
//max要跟其他的所有未排序的值作比较
for(var j=i+1;j<arr.length;j++){
if(arr[max]<arr[j]){
max = j
}
}
if(max != i){
var temp = arr[max]
arr[max] = arr[i]
arr[i] = temp
}
}
return arr
}
console.log( choiceSort([6,2,8,5,3,1,23]))
// 插入排序
// 希尔排序
// 快速排序
function quikSort(arr){
if(arr.length <= 1){
return arr
}
var middle = arr[0]
var left=[],right=[]
for(var i=1;i<arr.length;i++){
middle > arr[i]?left.push(arr[i]):right.push(arr[i])
}
return quikSort(left).concat(middle).concat(quikSort(right))
}
console.log(quikSort([76,33,1,46,2,11,46,32,14]))
// 归并排序