阿里算法有多强?看看这篇“前端排序算法大全”你就知道了!

1.选择排序


function selectionSort(arr) {
    var len = arr.length;
    var minIndex, temp;
    for (var i = 0; i < len - 1; i++) {
        minIndex = i;
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {     // 寻找最小的数
                minIndex = j;                 // 将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    return arr;
}

▲小编是一个有着5年工作经验的web前端架构师,关于web前端,自己有做材料的整合,一个完整学习web前端的路线,学习材料和工具。能够进我的群585928911收取,免费送给大家。希望你也能凭自己的努力,成为下一个优秀的程序员!

2.冒泡排序

function bubbleSort(arr) {  
    for(let i = 0,l=arr.length;i<l-1;i++) {
        for(let j = i+1;j<l;j++) { 
          if(arr[i]>arr[j]) {
                let tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
            }
        }
    }
    return arr;
}

3.插入排序

function insertionSort(arr) {
    var len = arr.length;
    var preIndex, current;
    for (var i = 1; i < len; i++) {
        preIndex = i - 1;
        current = arr[i];
        while(preIndex >= 0 && arr[preIndex] > current) {
            arr[preIndex+1] = arr[preIndex];
            preIndex--;
        }
        arr[preIndex+1] = current;
    }
    return arr;
}

4.快速排序

扫描二维码关注公众号,回复: 5992871 查看本文章
function qSort(arr) {
  if (arr.length == 0) {
      return [];
  }
  var left = [];
  var right = [];
  var pivot = arr[0];
  for (var i = 1; i < arr.length; i++) { // 注意这里的起始值,因为有一个作为flag了
      if (arr[i] < pivot) {
          left.push(arr[i]);
      } else {
          right.push(arr[i]);
      }
  }
  return qSort(left).concat(pivot, qSort(right));
}

5.链表

单向链表的添加:

function insert(newElement, item){
    var newNode = new Node(newElement);  // 新建一个节点
    var current = this.find(item);   //找到item的位置(current在js中是引用,类似于C语言指针)
    newNode.next = current.next;  //将新节点的后继指向item的后继
    current.next = newNode;  // 修改item节点的后继指向新节点
}

单向链表的删除:

// 首先要找到删除元素的上一个节点

function findPrevious (item) {
    var currentNode = this.head;
    while (!(currentNode.next === null) && (currentNode.element !== item)) {
    return currentNode;
    }
}
function remove (item) {
    var prevNode = this.findPrevious(item);
    var currentNode = this.find(item); // 查找到当前要删除的节点
    if (!(prevNode.next === null)) {
        prevNode.next = prevNode.next.next; //待删除节点的前驱的后继 指向 原本待删除节点的后继
        currentNode.next = null; // 释放节点,防止内存泄漏
    }
}

双向列表的添加:

// 插入节点,注意插入的链指向

function insert(newElement, item){
    var newNode = new Node(newElement);  // 新建一个节点
    var current = this.find(item);   //找到item的位置
    newNode.next = current.next;  //将新节点的后继指向item的后继
        newNode.previous = current;
        current.next = newNode;
        if (newNode.next !== null) {
                newNode.next.previous = newNode; // 将item原本的位置的前驱指向新节点
        }
}

双向链表的删除:

function remove (item) {
    var currentNode = this.find(item);
    if (!(currentNode === null)) {
        currentNode.previous.next = currentNode.next; // 删除节点的前驱的后继,指向删除节点的后继
        currentNode.next.previous = currentNode.previous; //删除节点的后继的前驱,指向删除节点的前驱
        currentNode.next = null; // 释放节点,防止内存泄漏
        currentNode.previous = null;
    } else {
        currentNode.previous.next = null; // 尾节点的前驱的后继指向null
        currentNode.previous = null; // 释放尾节点
    }
}

6.斐波那契数列

//递归方案

function gostair(stair){
  if(stair < 2){
    return stair;
}
return gostair(stair-1) + gostair(stair -2)
}

//动态规划方案

function gostair(n){
    let arr =  [];
    for(let i =  0;  i<=n;  i++){
      arr[i]  =  0;
    }
    if(n ==  1||n==2){
         return 1;
    }else{
        arr[1]  =  1;
        arr[2]  =  2;
        for(let j =  3;j<=n;j++){
        arr[j]  =  arr[j-1]+arr[j-2];
    }
    }
    return arr[n-1];
}

//迭代方案(指针移动方案)

function  gostair(n){
    let  first =  1; 
    let  last =  1;
    let result  =  1;
    for(let i=2;i<n;i++){
        result =  first +last;
        first =  last;
        last =  result;
    }
return result;
}

数组拍平

1.arr.join(',').split(',');
2.function flat(arr) {
var newarr = [];
return function flatten(arr) {
    for(let i =  0;i<arr.length;i++){
        if (Object.prototype.toString.call(arr[i]) === "[object Array") {
            newarr.concat(flatten(arr[i]))
        } else {
  newarr.push(arr[i]);
        }
    }(arr)
    return newarr
}
}

二分查找(前提是排序完成,最快的查找方法)

function find (arr, item) {
    var low = 0;  //设定下标
    var high = arr.length - 1; // 设定上标
    while (high >= low) {
        var mid = Math.floor((low + high) / 2);   //二分查找的关键
        if (arr[mid] === item) {
            return mid;
        }else if (arr[mid] > item) {
             high = mid;
        } else if (arr[mid] < item){
            low = mid;
        } else {
            return mid;
        }
    }
    return  -1;
}

浅拷贝

function extendCopy(p) {
var c = {};
for (var i in p) { 
c[i] = p[i];
}
return c;
}

深拷贝:循环调用浅拷贝

function deepCopy(p, c) {
 var c = c || {};
 for (var i in p) {
 if (typeof p[i] === 'object') {
 c[i] = (p[i].constructor === Array) ? [] : {};
 deepCopy(p[i], c[i]);
 } 
       else {
 c[i] = p[i];
 }
 }
 return c;
}

用代码实现二叉搜索树,写出相关方法查找最小值。 
(左子树上所有结点的值均小于它的根结点的值;右子树上所有结点的值均大于它的根结点的值; 
)

//定义节点

    function Node(data, left, right) {
        this.data = data;
        this.left = left;
        this.right = right;
    }

// 插入值

function insert (data) {
    var n = new Node(data, null, null); // 定义一个新节点
    if(this.root === null) {
        this.root = n;
    } else {
        var current = this.root;
        var parent;
        while (true) {
            parent = current;
            if (data < current.data) {
                current = current.left; // 比当前值小就放左边
                if (current === null) {
                    parent.left = n;
                    break;
                }
            } else {    // 比当前值大就放右边
                current = current.right;
                if(current === null){
                    parent.right = n;
                    break;
                }
            }
        }
    }
}

// 找最小值

function getSmallest (root) {
    // 一直往左子树上去找,找到没有左节点即找到了最小值
    var current = this.root || root;
    while (!(current.left === null)) {
        current = current.left;
    }
    return current;
}

函数防抖,函数节流 
防抖:debounce 操作结束后等待wait才执行一次。实例:keypress查询,防止点击提交按钮时的多次点击。

function debounce(fun,wait){
    var timeout  =  null;
    return function(){
    if(timeout !=  null) clearTimeout(timeout);
        timeout  =  setTimeout(fun,wait);
    }
}

如果immediate参数如果为true,则debounce函数会在调用时立刻执行一次function,等待时间内只执行一次

function debounce(fun,wait,immediate){
    var timeout;
    return function(){
        var context =  this,args =  arguments;
        var later =  function(){
        timeout =  null;
        if(!immediate) fun.apply(context,args);//immediate为false执行,操作结束后等待wait才执行一次
        };
        var callNow =  immediate &&   !timeout;
        clearTimeout(timeout);
        timeout =  setTimeout(later,wait);
        if(callNow)  fun.apply(context,args);//immediate为true执行,操作开始立即执行,

    }
}

节流:throttle 每隔多长时间执行一次函数,与防抖相比,节流函数多了一个 mustRun 属性,代表 mustRun 毫秒内,必然会触发一次 handler 实例:滑动加载图片懒加载

function  throttle(fun,wait,mustRun){
  var timeout,startTime =  new Date();
  return function(){
    var context =  this,args =  arguments,curTime =  new Date();
    clearTimeout(timeout);
    if(curTime -  startTime >=  mustRun){
        fun.apply(context,args);//mustRun内必触发一次
        startTime =  curTime;
    }else{
        timeout =  setTimeout(fun,wait);//每个wait触发一次
    }
  }

无限分类递归树

function toTree(data) {
   // 删除 所有 children,以防止多次调用
    data.forEach(function (item) {
        delete item.children;
    });
    // 将数据存储为 以 id 为 KEY 的 map 索引数据列
    var map = {};
    data.forEach(function (item) {
        map[item.id] = item;
    });
    var val = [];
    data.forEach(function (item) {
        // 以当前遍历项,的pid,去map对象中找到索引的id
        var parent = map[item.pid];
        // 好绕啊,如果找到索引,那么说明此项不在顶级当中,那么需要把此项添加到,他对应的父级中
        if (parent) {
            (parent.children || ( parent.children = [] )).push(item);
        } else {
            //如果没有在map中找到对应的索引ID,那么直接把 当前的item添加到 val结果集中,作为顶级
            val.push(item);
        }
    });
    return val;
}

获取两个时间中的所有年月

function getYearAndMonth(start, end) {
    var result = [];
    var starts = start.split('-');
    var ends = end.split('-');
    var staYear = parseInt(starts[0]);
    var staMon = parseInt(starts[1]);
    var endYear = parseInt(ends[0]);
    var endMon = parseInt(ends[1]);
    while (staYear <= endYear) {
        if (staYear === endYear) {
            while (staMon < endMon) {
                staMon++;
                result.push({year: staYear, month: staMon});
            }
            staYear++;
        } else {
            staMon++;
            if (staMon > 12) {
                staMon = 1;
                staYear++;
            }
            result.push({year: staYear, month: staMon});
        }
    }

    return result;
}

格式化返回的json结构

function formatJson(msg) {
///格式化返回的json结构可在pre标签展示
 var rep = "~";
 var jsonStr = JSON.stringify(msg, null, rep)
 var str = "";
 for (var i = 0; i < jsonStr.length; i++) {
 var text2 = jsonStr.charAt(i)
 if (i > 1) {
 var text = jsonStr.charAt(i - 1)
 if (rep != text && rep == text2) {
                str += "  "
            }
        }
        str += text2;
    }
    jsonStr = "";
 for (var i = 0; i < str.length; i++) {
 var text = str.charAt(i);
 if (rep == text){
 jsonStr += "  "
        }else {
            jsonStr += text;
        }
 if (i == str.length - 2){
 jsonStr += "  "
        }
    }
 return jsonStr;
}

转换字符首字母为小写

function toLowerCase(s) {  
///转换字符首字母为小写
 return s.toUpperCase().split(/\s+/).map(function(item, index) {  
 return item.slice(0, 1).toLowerCase() + item.slice(1);  
    }).join(' ');  
} 

数组去空格

function clear_arr_trim(array) {
///数组去空格
    for(var i = 0 ;i<array.length;i++)
    {
        if(array[i] == "" || typeof(array[i]) == "undefined")
        {
            array.splice(i,1);
            i= i-1;
        }
    }
    return array;
}

猜你喜欢

转载自blog.csdn.net/Ashin719/article/details/89460279