排序算法是基础的算法,也是每个前端人员需要掌握的基础,下面就让我们一起去实现一下这些JS的排序
一,用递归实现排序
1.第一步,我们首先来想一下如何找出一个数组中的最小值
(1)先从两个数中找出最小的数 [a,b]
let minOf2 = (numbers) => {
return numbers[0] < numbers[1] ? numbers[0] : numbers[1]
}
通过一个三元表达式就可以实现,当然我们可以优化一下代码,用析构赋值实现
let minOf2 = ([a, b]) => a < b ? a : b
调用:
minOf2.call(null, [1,2])
JS也有现成的API,内置了Math.min
Math.min(1,2)//1
Math.min.call(null,1,2)//1
Math.min.apply(null,[1,2])
(2)下面我们想一下,从三个数中找出最小值
let minOf3 = (numbers) => {
return minOf2([a, minOf2([b, c])])
};
我们可以使用递归的方法,调用minOf2函数,可以从三个数里面找出最小值
(3)四个数呢?
let minOf4 = (numbers) => {
return minOf2([a, minOf3([b, c, d])])
};
所以我们可以得出结论:求任意长度数组的最小值都可以通过minOf2实现
(4)不同数组长度,我们要反复声明,那么我们能不能用一个函数来实现呢?
let min = (numbers) => {
return min([numbers[0], min(numbers.slice(1))])
}
这是一个递归函数,每调用一次,就从数组中删除第一个元素
但是没有结束条件会陷入死循环,下面我们加入退出条件
let min = (numbers) => {
if (numbers.length > 2) {
return min([numbers[0], min(numbers.slice(1))])
} else {
return Math.min.apply(null, numbers)
}
}
这样我们就用递归的方法,找出了最小值
2.第二步,我们试一下利用上面的函数,把一个数组用递归的方式从小到大排列一下
(1)和找最小数一样,我们先从两个数开始
let sort2 = (numbers) => {
return numbers[0] < numbers[1] ? [numbers[0], numbers[1]] : [numbers[1], numbers[0]]
};
也是一个三元表达式就可以做到
(2)下面三个数排序
let sort3 = ([a,b,c])=>{
return [min([a,b,c]),sort2([?,?])
}
通过min函数找出最小值放在前面,然后后面两个进行比较,但是我们不知道a,b,c哪一个最小,所以后面的sort2里面的参数无法确定
这时,需要我们把最小的值从数组里面删去,然后进行后面两个数的排序
首先我们需要先创造一个函数,来求出最小值的下标
let minIndex = (numbers) =>
let intIndex = 0
for (let i = 1; i < numbers.length; i++) {
if (numbers[i] < numbers[index]) {
intIndex = i
}
}
return intIndex
}
这时我们可以得到最小值的下标,下面来修改我们的代码
let sort3 = (numbers) => {
let index = minIndex(numbers)
let minNum = numbers[index]
numbers.split(index, 1)
return [minNum].concat(sort2(numbers))
};
(3)接着四个数
let sort4 = (numbers) => {
let index = minIndex(numbers)
let minNum = numbers[index]
numbers.split(index, 1)
return [minNum].concat(sort3(numbers))
};
我们只要找出最小值,每递归一次,就把最小值从数组中删去,然后对新数组进行递归,最后将他们用concat链接起来,就实现了。
(4)下面我们还是想办法用一个函数实现
let sort = (numbers) => {
let index = minIndex(numbers)
let minNum = numbers[index]
numbers.split(index, 1)
return [minNum].concat(sort(numbers))
};
又是一个死循环,继续改进
let sort = (numbers) => {
if (numbers.length > 2) {
let index = minIndex(numbers)
let minNum = numbers[index]
numbers.splice(index, 1)
return [minNum].concat(sort(numbers))
} else {
return numbers[0] < numbers[1] ? numbers : numbers.reverse()
}
};
这样就可以实现了用递归进行数组排序。
二,用for循环实现排序(冒泡排序)
1,用冒泡排序实现,首先我们要先实现一下,两个变量如何进行交换
let swap = (array, i, j) => {
let temp = array[i]
array[i] = array[j]
array[j] = temp
}
这样我们就简单的实现了交换两个变量
下面用for循环实现一下排序
let sort = (arr) => {
for (var i = 0; i <= arr.length - 1; i++) { // 外层循环管趟数
for (var j = 0; j <= arr.length - i - 1; j++) { // 里面的循环管 每一趟的交换次数
// 内部交换2个变量的值 前一个和后面一个数组元素相比较
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
这样就利用for循环实现了排序