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