快速排序
快速排序的思想:
(1)在数据集中,选择一个元素作为"基准"
(2)所有小于“基准”的元素都移动到“基准”左边,所有大于“基准”的元素都移动到“基准”右边
(3) 对"基准"左右两边的子集,递归地重复(1)和(2)直到所有子集的长度都只有1个时停止
var nums = [85,24,63,45,45,17,31,96,50]
var fastSort = function(nums){
let len = nums.length
if(len < 2){
return nums
}
let _mi = parseInt((len -1 )/2)
let middle = nums.splice(_mi, 1)[0]
let left = []
let right = []
nums.forEach(item => {
if(item > middle){
right.push(item)
}else {
left.push(item)
}
});
return fastSort(left).concat([middle],fastSort(right))
}
let res = fastSort(nums)
console.log(":::",res);
sort的排序时间比快速排序还要快
sort排序
sort()在元素组上进行排序,不产生副本,并且返回值是对数组的引用
V8中的sort并不是单一的一种排序方法,而是根据数组长度来选择具体的方法,
当数组小于等于22,选择插入排序,大于22则远着快速排序
如果调用sort()方法时候没有使用参数,将按字母顺序对数组中的元素进行排序(按照ASCII排序,首先应该将数组的元素都转成字符串(如有必要),以便进行比较)
如果想按照其他标准进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字
1. (a,b) = > a -b (升序) ...... a是后面的数,如果a<b 返回小于0的数,交换位置
2. (a,b) = > b -a (降序)
做一道题:
给定一组非负整数nums, 重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数
例1: nums = [10,2] 输出: ‘210’
例2: nums = [3,30,34,5,9] 输出: ‘9533430’
先来捋一捋思路
1. 我们知道sort是根据ASCII比较的,所以在比较的时候可以将每个元素转为字符串.toString\()
2. 按照ASCII降序排列
3. “30” 的ASCII 大于 "3" 所以在排序的位置上 [30,3 ] 这样是降序,然而[3,30]组成的数要大于[30,3]
4. 所以我们可以比较 am = a.toString() + b.toString() // 303
bm = b.toString() + a.toString() // 330
5. 我们知道sort内部若返回小于0的数,则需要交换位置,显然 [5,9] "59" < "95" 需要交换位置
即 return “ba” - "ab" 也就是 return bm - am
6. 代码如下
var largestNumber = function(arr){
arr.sort((a,b)=>{
let am = a.toString() + b.toString()
let bm = b.toString() + a.toString()
return parseInt(bm) - parseInt(am)
})
return arr.join("")
}
参考文献
深入解析V8中sort的工作原理
快速排序(Quicksort)的Javascript实现