【JavaScript】前端必会的代码整理

222 阅读3分钟

更多leetcode题解在我的github上面:点击这里 后面还会持续进行更新~

常用数据结构和算法

这些代码都在leetcode上AC了题目

二分查找
const binarySearch = function (nums, target) {
  if(nums === null || nums.length === 0) {
    return -1
  }
  let left = 0,
    right = nums.length - 1
  while(left <= right) {
    let middle = left + Math.floor((right - left) / 2)
    if(target < nums[middle]) {
      right = middle - 1
    } else if(target > nums[middle]) {
      left = middle + 1
    } else {
      return middle
    }
  }
  return -1
}
二叉树非递归前序遍历
//先定义节点
/**
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */

var preorderTraversal = function(root) {
  if(!root) return []
  let result = []
  let stack = []
  stack.push(root)
  while(stack.length) {
    let current = stack.pop()
    result.push(current.val)
    if(current.right) {
      stack.push(current.right)
    }
    if(current.left) {
      stack.push(current.left)
    }
  }
  return result
};

二叉树非递归中序遍历
var inorderTraversal = function(root) {
   let result = []
   let stack = []
   while(root !== null) {
    stack.push(root)
    root = root.left
   }
   while(stack.length) {
     let current = stack.pop()
     result.push(current.val)
     current = current.right
     while(current) {
       stack.push(current)
       current = current.left
     }
   }
   return result
};
二叉树非递归后序遍历
var postorderTraversal = function (root) {
  if (!root) return []
  let result = []
  let head = root   //代表最近一次弹出的节点
  let current = null  //  代表当前栈顶节点
  let stack = [head]
  while (stack.length !== 0) {      //如果栈不为空,则循环遍历
    current = stack[stack.length - 1]  //将栈顶的值保存在current中
    if (current.left && head !== current.left && head !== current.right) { //如果存在左子树
      stack.push(current.left)   
    } else if (current.right && head !== current.right) { //如果结点存在右子树
      stack.push(current.right) 
    } else {
      result.push(stack.pop().val)
      head = current
    }
  }
  return result
};
二叉树的层序遍历,使用队列 广度优先遍历
var levelOrder = function (root) {
  if (root === null) {
    return [];
  }
  //创建队列并把起始节点入队(第一层)
  let queue = [],
    result = []
  queue.push(root)
  while (queue.length !== 0) {
    //从上一层节点拓展到下一层
    let level = [] //保存当前层过结果
    let size = queue.length //当前层的size
    for (let i = 0; i < size; i++) {
      node = queue.shift()
      level.push(node.val)
      if (node.left) {
        queue.push(node.left)
      }
      if (node.right) {
        queue.push(node.right)
      }
    }
    result.push(level)
  }
  return result
};
求二叉树的最大高度

      function fn(root) {
    return maxDepth(root)
  }

  //递归的定义:求出以root为根的左子树和右子树的高度
  function maxDepth(root) {
    //递归的出口
    if(root === null) {
      return 0
    }
    //递归的分解
    let leftHeight = maxDepth(root.left)
    let rightHeight = maxDepth(root.right)
    return Math.max(leftHeight, rightHeight) + 1
  }

判断回文字符串
var isPalindrome = function(s) {
    let length = s.length
    if(length === 0 || length === 1) return false
    let left = 0, right = length - 1
    while(left < right) {
      if(s[left++] != s[right--]) {
        return false
      }
    }
    return true
};
冒泡排序
 //冒泡排序,主要思想,从数组的第一项开始依次与下一项作比较,如果后者大于前者,则交换两元素位置
  bubbleSort = function (array) {
    var length = array.length
    for (var i = 0; i < length; i++) {
      for (var j = 0; j < length - 1 - i; j++) {
        if (array[j] > array[j + 1]) {
         swap(array, j, j + 1)
        }
      }
    }
  }
快速排序
function quickSort(array) {
  let left = 0, 
    right = array.length - 1
    index

  if (array.length > 1) {
    //index 将数组划分成较小值的数组和较大值的数组
    index = partition(array, left, right)
    if (left < index - 1) {
      quickSort(array, left, index - 1)
    }
    if (index < right) {
      quickSort(array, index, right)
    }
  }
}

function partition(array, left, right) {
  let point = array[Math.floor((right + left) / 2)] //取数组的中间值
  let i = left,
    j = right
  while (i <= j) {
    while (array[i] < point) {
      i++
    }
    while (array[j] > point) {
      j--
    }
    if (i <= j) {
         swap(array, i, j )
      i++
      j--
    }
  }
  return i
}
选择排序
  //选择排序,每次寻找数组中最小或最大的数,然后数组的第一项交换
   function selectSort(array) {
     let length = array.length,
      minIndex
      for(let i = 0; i < length; i++) {
        minIndex = i
        for(let j = 0; j <length; j++) {
          if(array[j] < array[minIndex]) {
            minIndex = j
          }
        }
        if(minIndex !== i) {
          swap(array, minIndex, i)
        }
      } 
   }

JavaScript常用代码

函数的防抖和节流
//函数节流

function fn() {}
var cd = false  //cdfalse代表技能可以使用

button.onclick = function() {
  if(!cd) {  
    cd = true
    setTimeout(()=> {
      fn()
      cd = false
    }, 3000)
  }
}

//防抖
function fn() {}
var timeId = null
button.onclick = function () {
  if(timeId) { //发现闹钟存在就砸掉闹钟
    window.clearTimeout(timeId)
  }
  timeId = setTimeout(() => {
    fn()
    timeId = null
  }, 5000)
}

递归实现深拷贝

var deepCopy = function(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

单例模式

let Single = (function() {
  let _instance = null
  function init(props) {
    return {
      publickMethod: function(){

      },
      value: props.value
    }
  }
  return function(props) {
    if(!_instance) {
      _instance = init(props)
    }
    return _instance
  }
})()
let instance = Single({value: 10})

发布订阅模式

  //发布订阅模式
  let Observer = function() {
    _message = {}
    return {
      //将订阅者注册的消息推到消息队列中,接收的参数时消息的类型和如何处理消息
      on(type, callback) {
        if(_message[type]) {
          _message[tyep] = [callback]
        } else {
          _message[tyep].push(callback)
        }
      },
      //发布事件
      emit(type, args) {
        if(!_message[type]) {
          return 
        }
        let events = {
          type,
          args: args || {}
        }
        let length = _message[type].length
        for(let i = 0; i < length; i++) {
          _message[type][i].call(this, events)
        }
      },
      //删除某个类型对应的回调函数
      remove(type) {
        if(_message[type]) {
          delete _message[type]
        }
      },
      once(type, callback) {
        on(type, (args) => {
          callback(args)
          remove(type)
        })
      }
    }
  }