前端常见的算法

197 阅读2分钟

冒泡排序:先拍第一个元素,经过一轮的循环

image.png

var a = [3,2,6,1]
for(let i =0;i<a.length;i++){
    for(let j =0;j<a.length-i-1;j++){
        if(a[j]>a[j+1]){
            let tmp = a[j]
            a[j] = a[j+1]
            a[j+1] = tmp
        }
    }
}
console.log(a)

插入排序:拿出一个元素,和其他元素相比,依次比较

image.png

var a = [3,1,2,6]
for(let i=0;i<a.length;i++){
    for(let j=i+1;j<a.length;j++){
        if(a[i]>a[j]){
            let tmp = a[i]
            a[i] = a[j] 
            a[j] = tmp
        }
        
    }
}

快速排序:使用二分法概念,找出中间元素,左右两侧分别和他比较经过递归,获取最终的排序结果

image.png

function fastSort(arr){
  if(arr.length<=1)return arr
  let midIndex = arr.length/2;
  //把原数组中中间元素剔除
  let midVal = arr.splice(midIndex,1)[0]
  let lefArray = []
  let rightArr = []
  for(let i = 0;i<arr.length;i++){
    let item = arr[i];
    item<midVal?lefArray.push(item):rightArr.push(item)
  }
  return fastSort(lefArray).concat(midVal,fastSort(rightArr))
}

同样的,我们也可使用es6提供的方法 arr.sort,直接实现排序

打乱顺序

function getL (list){
  let arr = []
  if(list.length>1){
    for(let i=0;i<list.length;i++){
      let left =list[i]
      let a = [...list]
      a.splice(i,1)
      let pre = getL(a)
      console.log(pre)
      for(let i=0;i<pre.length;i++){
        let tmp1 = [left,...pre[i]]
        arr.push(tmp1)
      }

    }
  } else {
    arr.push(list)
  }
  return arr
}

promise简单实现

promise的all方法是只有全部成功才会进入,否则进入catch。race是第一个成功就进入then,否则进入catch

var pro1 = ()=>{
  return new Promise((res,rej)=>{
    res('pro12')
    console.log('pro12')
  })
}
var pro2 = ()=>{
  return new Promise((res,rej)=>{
    rej('pro23')
    console.log('pro23')
  })
}
var pro3 = ()=>{
  return new Promise((res,rej)=>{
    res('pro33')
    console.log('pro33')
  })
}

// pro12 pro23 pro23error
Promise.all([pro1(),pro2()]).then(res=>{console.log(res+"all res")}).catch(rej=>{console.log(rej+"error")})  

// pro12 pro33 [pro12,pro33]
Promise.all([pro1(),pro3()]).then(res=>{console.log(res)}).catch(rej=>{console.log(rej+"error")})  

//  pro23 pro12 pro33 pro23race error
Promise.race([pro2(),pro1(),pro3()]).then(res=>{console.log(res+"race res")}).catch(rej=>{console.log(rej+"race error")}) 

//  pro12 pro23 pro33 pro23race res
Promise.race([pro1(),pro2(),pro3()]).then(res=>{console.log(res+"race res")}).catch(rej=>{console.log(rej+"race error")}) 

const status=['pending,fulfilled','reject']
class Promise1{
  constructor(callback){
    this.status = status[0]
    this.val = null //成功 
    this.res = null  //失败
    callback(this.resolve,this.reject)
    this.resolveArr = [];
    this.rejectArr = [];
  }
  resolve=(val)=>{
    if(this.status===status[0]){
      this.status = status[1]
      this.val = val
      this.resolveArr.forEach(fun=>fun(val))
    }
  }
  reject=(val)=>{
    if(this.status===status[0]){
      this.status = status[2]
      this.res = val
      this.rejectArr.forEach(fun => fun(val)) 
    }
  }
  then=(onFullFill,onReject)=>{
    if(this.status === status[0]){
      return new Promise1((resolve,reject)=>{
        this.resolveArr.push(val=>{
          try {
            const result =  onFullFill(val); 
            // 如果返回是promise的话 继续then方法
           if(result instanceof Promise1){
             result.then(resolve,reject)
           } else {
             resolve(result)
           }
          } catch (error) {
            reject(error)
          }
        })
        this.rejectArr.push(val=>{
          try {
            const result =  onReject(val); 
            // 如果返回是promise的话 继续then方法
           if(result instanceof Promise1){
             result.then(resolve,reject)
           } else {
             resolve(result)
           }
          } catch (error) {
            reject(error)
          }
        })
       })
    }
  }
}

数组打乱顺序

 function shuffle(arr){
  let m = arr.length, t,i

  while(m){
    i = Math.floor(Math.random() * m--)
    console.log(i)
    t = arr[m]
    arr[m] = arr[i];
    arr[i] = t;
  }
  
  return arr
}

instanceof 实现

function ins(left,right){
  let l = left.__proto__
  let r = right.prototype
  while(true){
    if(l=== null) return false
    if(l === right) return true
    l = l.__proto__
  }
}

寄生组合继承

function S(name){
  this.name = name
}
function C(name){
  S.call(this,name)
}
var b = Object.create(s.prototype)
C.prototype = b
b.constructor = C

bind 实现

Function.prototype.bind = function(ctx){
  var arg =[...arguments].slice(1)
  var that = this
  return function(){
    return that.apply(ctx,arg.concat(...arguments))
  }
}

klh

function kla(){
  var arg = [...arguments]
  var add = function(){
    arg.push(...arguments)
    return add
  }
  add.toString = ()=>{
    return arg.reduce((sum,item)=>sum+item)
  }
  return add()
}

new的过程

function ne(fn,...rest){
  var a = new Object()
  a.__proto__ = fn.prototype
  var res = fn.apply(a,rest)
  return res instanceof Object ?res :Object
}

重复子串的查找过程

image.png

var longestCommonSubsequence = function(text1, text2) {
  const txt1Arr = text1.split("")
  const txt2Arr = text2.split("")
  const m = txt1Arr.length
  const n = txt2Arr.length
  const arr = Array(m+1).fill(0).map(item=>new Array(n+1).fill(0))
  for(let i=1;i<=m;i++){
      let txt1 = txt1Arr[i-1]
      for(let j=1;j<=n;j++){
          let txt2 = txt2Arr[j-1]
          if(txt1 === txt2){
              arr[i][j]=arr[i-1][j-1]+1
          } else {
            arr[i][j] = Math.max(arr[i-1][j],arr[i][j-1])
          }
      }
  }
  return arr[m][n]

};

深度优先遍历

function getCurList(list){
  let arr = [], stack = [list]
  while(stack.length!==0){
    let tmp = stack.pop()
    arr.push(tmp.value)
    if(tmp.childRight){
      stack.push(tmp.childRight)
    }
    if(tmp.childLeft){
      stack.push(tmp.childLeft)
    }
  }
  return arr
}

树结构转化为json

function treeToJ(tree){
  let arr = []
  return function getList(tree){
    tree.forEach(item=>{
      arr.push({
        id:item.id,
        pid:item.pid
      })
      if(item.children && Array.isArray(item.children)){
       return getList(item.children)
      }
    })
    return arr
  }(tree)
}

json转树

function getTree(obj){
  let tree = []

  let objClone = {}
  obj.forEach(item=>{
    objClone[item.id] = item
  })
  console.log(objClone)
  obj.forEach(item=>{
    if(!item.pid){
      tree.push(item)
    } else {
      objClone[item.pid].children || (objClone[item.pid].children = []).push(item)
    }
    console.log(item)
  })
  return tree
}

节流防抖

function throttle(fn,wait=300){
  var timer = null
  return function(){
    let ctx = this
    let arg =[...arguments]
    if(timer)return
    timer = setTimeout(function(){
      fn.apply(ctx,arg)
      timer = null
    })

  }
}
function debounce(){
  var timer = null
  return function(){
    let ctx = this
    let arg =[...arguments]
    if(timer){
      clearTimeout(timer)
      return;
    }
    timer = setTimeout(function(){
      fn.apply(ctx,arg)
      timer = null
    })

  }
}

返回任意顺序

 function shuffle(arr){
  let m = arr.length, t,i

  while(m){
    i = Math.floor(Math.random() * m--)
    console.log(i)
    t = arr[m]
    arr[m] = arr[i];
    arr[i] = t;
  }
  
  return arr
}

大厂面试总结:www.jianshu.com/p/796a6e132… 常用的算法:www.conardli.top/docs/dataSt… 有一个面试:mp.weixin.qq.com/s?__biz=MzA… 大厂:mp.weixin.qq.com/s?__biz=MzA…