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 相关文章推荐
如何确保JavaScript的执行顺序 之实战篇
Mar 03 Javascript
为什么要在引入的css或者js文件后面加参数的详细讲解
May 03 Javascript
jquery获取radio值实例
Oct 16 Javascript
JS+CSS实现美化的下拉列表框效果
Aug 11 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
Oct 29 Javascript
Boostrap模态窗口的学习小结
Mar 28 Javascript
使用jQuery调用XML实现无刷新即时聊天
Aug 07 Javascript
jquery获取transform里的值实现方法
Dec 12 jQuery
vue filters的使用详解
Jun 11 Javascript
JavaScript命名空间模式实例详解
Jun 20 Javascript
JavaScript实现省市区三级联动
Feb 13 Javascript
js+h5 canvas实现图片验证码
Oct 11 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 memcache扩展的三种安装方法
2009/04/26 PHP
PHP中使用unset销毁变量并内存释放问题
2012/07/05 PHP
php使用exec shell命令注入的方法讲解
2013/11/12 PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
2018/08/21 PHP
PHP实现时间日期友好显示实现代码
2019/09/08 PHP
一端时间轮换的广告
2006/06/26 Javascript
jquery创建div 实现代码
2009/04/27 Javascript
JavaScript call apply使用 JavaScript对象的方法绑定到DOM事件后this指向问题
2011/09/28 Javascript
javascript模版引擎-tmpl的bug修复与性能优化分析
2011/10/23 Javascript
中文路径导致unitpngfix.js不正常的解决方法
2013/06/26 Javascript
Js日期选择自动填充到输入框(界面漂亮兼容火狐)
2013/08/02 Javascript
jQuery插件MixItUp实现动画过滤和排序
2015/04/12 Javascript
深入浅出ES6新特性之函数默认参数和箭头函数
2016/08/01 Javascript
原生JS实现-星级评分系统的简单实例
2016/08/21 Javascript
React Native react-navigation 导航使用详解
2017/12/01 Javascript
vue+iview/elementUi实现城市多选
2019/03/28 Javascript
[53:29]完美世界DOTA2联赛循环赛 DM vs Matador BO2第二场 11.04
2020/11/05 DOTA
python2.7删除文件夹和删除文件代码实例
2013/12/18 Python
python实现一次创建多级目录的方法
2015/05/15 Python
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
Eclipse和PyDev搭建完美Python开发环境教程(Windows篇)
2016/11/16 Python
python多进程实现文件下载传输功能
2018/07/28 Python
PyCharm搭建Spark开发环境的实现步骤
2019/09/05 Python
DJANGO-URL反向解析REVERSE实例讲解
2019/10/25 Python
python 字典访问的三种方法小结
2019/12/05 Python
Python更新所有已安装包的操作
2020/02/13 Python
viagogo波兰票务平台:演唱会、体育比赛、戏剧门票
2018/04/23 全球购物
上海某公司.net方向笔试题
2014/09/14 面试题
服务承诺书怎么写
2014/05/24 职场文书
节约粮食标语
2014/06/18 职场文书
建筑施工安全生产责任书
2014/07/22 职场文书
岗位工作说明书
2014/07/29 职场文书
放假通知
2015/04/14 职场文书
致毕业季:你如何做好自己的职业生涯规划书?
2019/07/01 职场文书
为Java项目添加Redis缓存的方法
2021/05/18 Redis
MybatisPlus代码生成器的使用方法详解
2021/06/13 Java/Android