JS常见算法详解


Posted in Javascript onFebruary 28, 2017

算法是程序的灵魂,一个优秀前端工程师对算法也是要有所了解的,本文总结了我们在开发、面试中经常会遇到的基础算法,使用原生JS实现,未必是最优解,可以互相探讨。

为了便于查看,简单分下类,本文也会持续更新。

排序算法

1. 冒泡排序

function bubbleSort(arr){
 var i = j = 0;
 for(i=1;i<arr.length;i++){
 for(j=0;j<=arr.length-i;j++){
 var temp = 0;
 if(arr[j]>arr[j+1]){
 temp = arr[j];
 arr[j] = arr[j+1];
 arr[j+1] = temp;
 }
 }
 }
}

2. 快速排序

function quickSort(arr,l,r){
 if(l < r){
 var i = l, j = r, x = arr[i];
 while(i<j){
 while(i<j && arr[j]>x)
 j--;
 if(i<j)
 //这里用i++,被换过来的必然比x小,赋值后直接让i自加,不用再比较,可以提高效率
 arr[i++] = arr[j];
 while(i<j && arr[i]<x)
 i++;
 if(i<j)
 //这里用j--,被换过来的必然比x大,赋值后直接让j自减,不用再比较,可以提高效率
 arr[j--] = arr[i];
 }
 arr[i] = x; 
 quickSort(arr, l, i-1);
 quickSort(arr, i+1, r);
 }
}

3. 二路归并

PS:将两个按值有序序列合并成一个按值有序序列,则称之为二路归并排序。

function merge(left, right) {
 var result = [],
  il = 0,
  ir = 0;
 while (il < left.length && ir < right.length) {
  if (left[il] < right[ir]) {
   result.push(left[il++]);
  } else {
   result.push(right[ir++]);
  }
 }
 while(left[il]){
  result.push(left[il++]);
 }
 while(right[ir]){
  result.push(right[ir++]);
 }
 return result;
}

字符串操作

1. 判断回文字符串

function palindrome(str){
 // \W匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
 var re = /[\W_]/g;
 // 将字符串变成小写字符,并干掉除字母数字外的字符
 var lowRegStr = str.toLowerCase().replace(re,'');
 // 如果字符串lowRegStr的length长度为0时,字符串即是palindrome
 if(lowRegStr.length===0)
 return true;
 // 如果字符串的第一个和最后一个字符不相同,那么字符串就不是palindrome
 if(lowRegStr[0]!=lowRegStr[lowRegStr.length-1])
 return false;
 //递归
 return palindrome(lowRegStr.slice(1,lowRegStr.length-1));
}

2. 翻转字符串

2.1 思路1:反向遍历字符串

function reverseString(str){
 var tmp = '';
 for(var i=str.length-1;i>=0;i--)
 tmp += str[i];
 return tmp
}

2.2 思路2:转化成array操作。

function reverseString2(str){
 var arr = str.split("");
 var i = 0,j = arr.length-1;
 while(i<j){
  tmp = arr[i];
  arr[i] = arr[j];
  arr[j] = tmp;
  i++;
  j--;
 }
 return arr.join("");
}

PS:什么?你要问为啥不直接操作str? 因为str[i]是只读的,不能str[0]=str[1]这样操作。

再PS:如果允许用reverse(),也可以用'str'.split('').reverse().join('')实现。

3. 生成指定长度随机字符串

PS:配合模糊等效果可以生成个验证码- -

function randomString(n){
 var str = 'abcdefghijklmnopqrstuvwxyz0123456789';
 var tmp = '';
 for(var i=0;i<n;i++)
  tmp += str.charAt(Math.round(Math.random()*str.length));
 return tmp;
}

4. 统计字符串中次数最多字母

PS:利用Object中key的唯一性,利用key来进行筛选,然后计数。

function findMaxDuplicateChar(str) {
 if(str.length == 1) {
  return str;
 }
 var charObj = {};
 for(var i = 0; i < str.length; i++) {
  if(!charObj[str.charAt(i)]) {
   charObj[str.charAt(i)] = 1;
  } else {
   charObj[str.charAt(i)] += 1;
  }
 }
 var maxChar = '',
  maxValue = 1;
 for(var k in charObj) {
  if(charObj[k] >= maxValue) {
   maxChar = k;
   maxValue = charObj[k];
  }
 }
 return maxChar + ':' + maxValue;
}

数组操作

1. 数组去重

PS: 还是利用Object中key的唯一性,利用key来进行筛选。

function unique(arr){
 var obj = {}
 var data = []
 for(var i in arr){
  if(!obj[arr[i]]){
   obj[arr[i]] = true;
   data.push(arr[i]);
 }
 }
 return data;
}

2. Number数组中最大差值

function getMaxProfit(arr){
 var min = arr[0], max = arr[0];
 for(var i=0;i<arr.length;i++){
  if(arr[i]<min)
   min = arr[i];
 if(arr[i]>max)
  max = arr[i];
 }
 return max - min;
}

其他常见算法

1. 阶乘

1.1 非递归实现

function factorialize(num) {
 var result = 1;
 if(num < 0) return -1;
 if(num == 0 || num == 1) return 1;
 while(num>1)
  result *= num--;
 return result;
}

1.2 递归实现

function factorialize(num) {
 var result = 1;
 if(num < 0) return -1;
 if(num == 0 || num == 1) return 1;
 if(num > 1){
  return num*factorialize(num-1);
 }
}

2. 生成菲波那切数列

PS:斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列主要考察递归的调用。通过定义fibo[i] = fibo[i-1]+fibo[i-2];来生成斐波那契数组。

2.1 强行递归实现

function getfib(n){
 if(n == 0)
 return 0;
 if(n == 1)
  return 1;
 if(n > 1){
 return getfib(n-1) + getfib(n-2);
 }
}
function fibo(len){
 var fibo = [];
 for(var i=0;i<len;i++)
 fibo.push(getfib(i));
 return fibo;
}

2.2 简约非递归版

function getFibonacci(n) {
 var fibarr = [];
 var i = 0;
 while(i < n) {
  if(i <= 1) {
   fibarr.push(i);
  } else {
   fibarr.push(fibarr[i - 1] + fibarr[i - 2])
  }
  i++;
 }
 return fibarr;
}

3. 二分查找

PS:二分查找又称折半查找,是在有序数组查找中用到的较为频繁的一种算法,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。

3.1 非递归实现

function binary_search(arr, key) {
 var low = 0,
  high = arr.length - 1;
 while(low <= high){
  var mid = parseInt((high + low) / 2);
  if(key == arr[mid]){
   return mid;
  }else if(key > arr[mid]){
   low = mid + 1;
  }else if(key < arr[mid]){
   high = mid -1;
  }
 }
 return -1;
};

3.2 递归实现

function binary_search2(arr, low, high, key) {
 if(low > high)
  return -1;
 var mid = parseInt((low + high)/2);
 if(key == arr[mid])
  return mid;
 else if(key > arr[mid])
  return binary_search2(arr, mid+1, high, key);
 else if(key < arr[mid])
  return binary_search2(arr, low, mid-1, key);
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
在页面加载完成后通过jquery给多个span赋值
May 21 Javascript
javascript将url中的参数加密解密代码
Nov 17 Javascript
基于jQuery插件实现点击小图显示大图效果
May 11 Javascript
利用策略模式与装饰模式扩展JavaScript表单验证功能
Feb 14 Javascript
利用Javascript裁剪图片并存储的简单实现
Mar 13 Javascript
jQuery.form.js的使用详解
Jun 14 jQuery
javascript ES6 新增了let命令使用介绍
Jul 07 Javascript
ReactNative 之FlatList使用及踩坑封装总结
Nov 29 Javascript
浅析vue-router原理
Oct 19 Javascript
Next.js项目实战踩坑指南(笔记)
Nov 29 Javascript
微信小程序的tab选项卡的实现效果
May 15 Javascript
layui 数据表格 根据值(1=业务,2=机构)显示中文名称示例
Oct 26 Javascript
vue.js树形组件之删除双击增加分支实例代码
Feb 28 #Javascript
jQuery插件MovingBoxes实现左右滑动中间放大图片效果
Feb 28 #Javascript
jQuery中的on与bind绑定事件区别实例详解
Feb 28 #Javascript
利用angularjs1.4制作的简易滑动门效果
Feb 28 #Javascript
js 转义字符及URI编码详解
Feb 28 #Javascript
基于Bootstrap漂亮简洁的CSS3价格表(附源码下载)
Feb 28 #Javascript
基于vue2.0+vuex+localStorage开发的本地记事本示例
Feb 28 #Javascript
You might like
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
2018/05/12 PHP
PHP设计模式之数据访问对象模式(DAO)原理与用法实例分析
2019/12/12 PHP
对 lightbox JS 图片控件进行了一下改造, 使其他支持复杂的图片说明
2010/03/20 Javascript
javascript通过navigator.userAgent识别各种浏览器
2013/10/25 Javascript
js中把JSON字符串转换成JSON对象最好的方法
2014/03/21 Javascript
浅谈jQuery中对象遍历.eq().first().last().slice()方法
2014/11/26 Javascript
浅谈JavaScript中的对象及Promise对象的实现
2015/11/15 Javascript
JS组件Bootstrap Select2使用方法解析
2016/05/30 Javascript
什么是JavaScript中的结果值?
2016/10/08 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
2016/10/21 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
基于js 各种排序方法和sort方法的区别(详解)
2018/01/03 Javascript
详解plotly.js 绘图库入门使用教程
2018/02/23 Javascript
Nodejs核心模块之net和http的使用详解
2019/04/02 NodeJs
微信小程序--特定区域滚动到顶部时固定的方法
2019/04/28 Javascript
微信小程序绘制图片发送朋友圈
2019/07/25 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
2020/04/21 Javascript
跟老齐学Python之通过Python连接数据库
2014/10/28 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
深入理解Django中内置的用户认证
2017/10/06 Python
django框架实现一次性上传多个文件功能示例【批量上传】
2019/06/19 Python
Win10下Python3.7.3安装教程图解
2019/07/08 Python
手把手教你Python yLab的绘制折线图的画法
2019/10/23 Python
OpenCV实现机器人对物体进行移动跟随的方法实例
2020/11/09 Python
HTML5中drawImage用法分析
2014/12/01 HTML / CSS
Mistine官方海外旗舰店:泰国国民彩妆品牌
2016/12/28 全球购物
Clarria化妆品官方网站:购买天然和有机化妆品系列
2018/04/08 全球购物
美国鲜花递送:UrbanStems
2021/01/04 全球购物
什么是Oracle的后台进程background processes?都有哪些后台进程?
2012/04/26 面试题
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
淘宝客服专员岗位职责
2014/04/11 职场文书
2014年医院十一国庆节活动方案
2014/09/15 职场文书
中学生综合素质自我评价
2015/03/06 职场文书
永不妥协观后感
2015/06/10 职场文书
【DOTA2】当街暴打?PSG LGD vs VG - DPC 2022 WINTER TOUR CN
2022/04/02 DOTA