前端常见算法


快速排序

找到一个基准点,数组被该基准点分为两部分,依次与该基准点数据比较,如果比它小,放左边;反之,放右边。左右分别用一个空数组去存储比较后的数据。最后递归执行上述操作,直到数组长度 <= 1。

function quickSort(arr, i, j) {
	if(i > j) return arr;
	const pivotIndex = i;
	const pivot = arr[i];
	while(i < j) {
		while(arr[j] > pivot) j--;
		while(arr[i] <= pivot && i < j) i++;
		if(arr[i] !== arr[j]) {
			arr[j] += arr[i];
			arr[i] = arr[j] - arr[i];
			arr[j] -= arr[i];
		}
	}
	if(arr[j] !== arr[pivotIndex]) {
		arr[j] += arr[pivotIndex];
		arr[pivotIndex] = arr[j] - arr[pivotIndex];
		arr[j] -= arr[pivotIndex];
	}
	quickSort(arr, pivotIndex, j - 1);
	quickSort(arr, j + 1, arr.length - 1);
	return arr;
}
function quickSort2(arr) {
	if (arr.length <= 1) {
		return arr;
	}
  const pivotIndex = Math.floor(arr.length / 2);
  const pivot = arr.splice(pivotIndex, 1)[0];
  const left = [];
  const right = [];
  arr.forEach(data => {
	  if (data < pivot) {
		  left.push(data);
	  } else {
		  right.push(data);
	  }
	});
  return quickSort2(left).concat([pivot], quickSort2(right));
};
function quickSort3(arr) {
  return arr.length <= 1 ? arr : quickSort3(arr.slice(1).filter(item => item <= arr[0])).concat(arr[0], quickSort(arr.slice(1).filter(item => item > arr[0])));
}

冒泡排序

每一次对比相邻两个数据的大小,小的排在前面,如果前面的数据比后面的大就交换这两个数的位置。

function bubbleSort1(arr) {
	// 循环周期数
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {
                var temp = arr[j+1]; 
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
	return arr;
}

归并排序

把一个数组分为两个数组,左边排好序,右边排好序,然后合并到一起排序

function merge(left, right) {
  var tmp = [];

  while (left.length && right.length) {
    if (left[0] < right[0]) {
      tmp.push(left.shift());
    } else {
      tmp.push(right.shift());
	}
  }
  
  return tmp.concat(left, right);
}

function mergeSort(arr) {
  if (arr.length === 1) 
    return arr;

  const mid = ~~(arr.length / 2);
  const left = arr.slice(0, mid);
  const right = arr.slice(mid);

  return merge(mergeSort(left), mergeSort(right));
}

选择排序

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
(左比较元素,右比较数组)

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;
}

插入排序

将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据。适用于少量数据的排序。
(左数组,右插入元素)

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

时间复杂度


二叉查找树

function BinarySearchTree () {
	var Node = function(key) {
	    this.key = key,
	    this.left = null,
	    this.right = null
	}
    var root = null
       
    //插入节点
    this.insert = function(key) {
        var newNode = new Node(key)
        if(root === null) {
            root = newNode
        } else {
            insertNode(root, newNode)
        }
    }
    var insertNode = function(node, newNode) {
        if (newNode.key <= node.key) {
            if (node.left === null) {
                node.left = newNode
            }else {
                insertNode(node.left, newNode)
            }
        }else {
            if (node.right === null) {
                node.right = newNode
            }else {
                insertNode(node.right, newNode)
            }
        }
    } 
       
    //实现中序遍历(左-根-右)
    this.inOrderTraverse = function() {
        inOrderTraverseNode(root)
    }
    var inOrderTraverseNode = function(node) {
        if (node !== null) {
            inOrderTraverseNode(node.left)
            console.log(node.key)
            inOrderTraverseNode(node.right)
        }
    }
    // 实现先序遍历(根-左-右)
    this.preOrderTraverse = function() {
        preOrderTraverseNode(root)
    }
    var preOrderTraverseNode = function(node) {
        if (node !== null) {
            console.log(node.key)
            preOrderTraverseNode(node.left)
            preOrderTraverseNode(node.right)
        }
    }

    // 实现后序遍历(左-右-根)
    this.postOrderTraverse = function() {
        postOrderTraverseNode(root)
    }
    var postOrderTraverseNode = function(node) {
        if (node !== null) {
            postOrderTraverseNode(node.left)
            postOrderTraverseNode(node.right)
            console.log(node.key)
        }
    }

	// 查找最小值
    this.findMin = function() {
        return minNode(root)
    }
    var minNode = function(node) {
        if (node) {
            while (node && node.left !== null) {
                node = node.left
            }
            return node.key
        }
        return null
    }
    
    // 查找最大值
    this.findMax = function() {
        return maxNode(root)
    }
    var maxNode = function (node) {
        if(node) {
            while (node && node.right !== null) {
                node =node.right
            }
            return node.key
        }
        return null
    }

	this.search = function(key) {
	    return searchNode(root, key)
	}
	var searchNode = function(node, key) {
        if (node === null) {
            return false
        }
        if (key < node.key) {
            return searchNode(node.left, key)
        }else if (key > node.key) {
            return searchNode(node.right, key)
        }else {
            return true
        }
    }
// 移除节点
    this.remove = function(key) {
        removeNode(root,key)
    }
    var removeNode = function(node, key) {
        if (node === null) {
            return null
        }
        if (key < node.key) {
            node.left = removeNode(node.left, key)
            return node
        }else if(key > node.key) {
            node.right = removeNode(node.right,key)
            return node
        }else{
            //需要移除的节点是一个叶子节点
            if (node.left === null && node.right === null) {
                node = null
                return node
            }
            //需要移除的节点包含一个子节点
            if (node.letf === null) {
                node = node.right
                return node
            }else if (node.right === null) {
                node = node.left
                return node
            }
            //需要移除的节点包含两个子节点
            var aux = findMinNode(node.right)
            node.key = aux.key
            node.right = removeNode(node.right, axu.key)
            return node
        }
    }
    var findMinNode = function(node) {
        if (node) {
            while (node && node.left !== null) {
                node = node.left
            }
            return node
        }
        return null
    }
}

更多内容:JavaScript实现简单二叉查找树


const timeout = ms => new Promise((resolve, reject) => {
	setTimeout(() => {
		resolve();
	}, ms);
});

const ajax1 = () => timeout(2000).then(() => {
	console.log('1');
	return 1;
});

const ajax2 = () => timeout(1000).then(() => {
	console.log('2');
	return 2;
});

const ajax3 = () => timeout(2000).then(() => {
	console.log('3');
	return 3;
});


mergePromise([ajax1, ajax2, ajax3]).then(data => {
	console.log('done');
	console.log(data); // data 为 [1, 2, 3]
});

参考自:
js十大排序算法详解


合并数组

/* 合并数组 */
var a = [1, 2, 3];
var b = [4, 5, 6];
Array.prototype.push.apply(a, b);	//a=[1,2,3,4,5,6]


bind()

if (!Function.prototype.bind) {
    Function.prototype.bind = function () {
        var self = this,                        // 保存原函数
            context = [].shift.call(arguments), // 保存需要绑定的this上下文
            args = [].slice.call(arguments);    // 剩余的参数转为数组
        return function () {                    // 返回一个新函数
            self.apply(context, [].concat.call(args, [].slice.call(arguments)));
        }
    }
}


debounce

function debounce(fn, delay) {
  var ctx;
  var args;
  var timer = null;

  var later = function () {
    fn.apply(ctx, args);
    // 当事件真正执行后,清空定时器
    timer = null;
  };

  return function () {
    ctx = this;
    args = arguments;
    // 当持续触发事件时,若发现事件触发的定时器已设置时,则清除之前的定时器
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    // 重新设置事件触发的定时器
    timer = setTimeout(later, delay);
  };
}

throttle

function throttle(fn, delay) {
  var ctx;
  var args;
  // 记录上次触发事件
  var previous = Date.now();

  var later = function () {
    fn.apply(ctx, args);
  };

  return function () {
    ctx = this;
    args = arguments;
    var now = Date.now();
    // 本次事件触发与上一次的时间比较
    var diff = now - previous - delay;

    // 如果隔间时间超过设定时间,即再次设置事件触发的定时器
    if (diff >= 0) {
      // 更新最近事件触发的时间
      previous = now;
      setTimeout(later, delay);
    }
  };
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值