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客户端脚本的设计和应用
Aug 21 Javascript
获取DOM对象的几种扩展及简写
Oct 09 Javascript
jquery实现的元素的left增加N像素 鼠标移开会慢慢的移动到原来的位置
Mar 21 Javascript
jQuery无刷新切换主题皮肤实例讲解
Oct 21 Javascript
JavaScript File分段上传
Mar 10 Javascript
ArtEditor富文本编辑器增加表单提交功能
Apr 18 Javascript
node.js从数据库获取数据
May 08 Javascript
jQuery插件pagination实现无刷新分页
May 21 Javascript
JavaScript实现DOM对象选择器
Sep 24 Javascript
layer弹出层自定义提交取消按钮的例子
Sep 10 Javascript
使用p5.js实现动态GIF图片临摹重现
Oct 23 Javascript
如何在 Vue 表单中处理图片
Jan 26 Vue.js
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
咖啡常见的种类
2021/03/03 新手入门
怎样在PHP中通过ADO调用Asscess数据库和COM程序
2006/10/09 PHP
php 短链接算法收集与分析
2011/12/30 PHP
apache配置虚拟主机的方法详解
2013/06/17 PHP
iframe子页面获取父页面元素的方法
2013/11/05 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
jQuery实现自定义右键菜单的树状菜单效果
2015/09/02 Javascript
基于JQuery实现仿网易邮箱全屏动感滚动插件fullPage
2015/09/20 Javascript
jqGrid 学习笔记整理——进阶篇(一 )
2016/04/17 Javascript
Angular弹出模态框的两种方式
2017/10/19 Javascript
微信小程序module.exports模块化操作实例浅析
2018/12/20 Javascript
vue回到顶部监听滚动事件详解
2019/08/02 Javascript
解决layui-open关闭自身窗口的问题
2019/09/10 Javascript
Vue状态模式实现窗口停靠功能(灵动、自由, 管理后台Admin界面)
2020/03/06 Javascript
使用js原生实现年份轮播选择效果实例
2021/01/12 Javascript
Python中的index()方法使用教程
2015/05/18 Python
Python for Informatics 第11章之正则表达式(四)
2016/04/21 Python
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
浅谈python numpy中nonzero()的用法
2018/04/02 Python
Python3 串口接收与发送16进制数据包的实例
2019/06/12 Python
Python代码需要缩进吗
2020/07/01 Python
python正则表达式re.match()匹配多个字符方法的实现
2021/01/27 Python
HTML5打开手机扫码功能及优缺点
2017/11/27 HTML / CSS
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
波兰运动鞋网上商店:e-Sporting
2018/02/16 全球购物
可口可乐唇膏:Lip Smackers
2019/08/27 全球购物
致400米运动员广播稿
2014/02/07 职场文书
大学学习个人的自我评价
2014/02/18 职场文书
我的小天地教学反思
2014/04/30 职场文书
委托书英文
2015/01/28 职场文书
2015年计生工作总结范文
2015/04/24 职场文书
2015年度保密工作总结
2015/04/24 职场文书
幼儿园六一主持词
2015/06/30 职场文书
Python基础之常用库常用方法整理
2021/04/30 Python
python和anaconda的区别
2022/05/06 Python
Redis基本数据类型Set常用操作命令
2022/06/01 Redis