记录一下三种排序方法。
一、冒泡排序
想象下水里的气泡,小的泡泡在下面,大的泡泡在上面。若给定nums数组使其从小到大排序,冒泡的关键点在于,相邻的两个元素 nums[ j ] 和 nums[ j + 1] 比较,需要把大的往后放。
冒泡排序代码:
/**
* 冒泡排序,从小到大
* @param {Array} ary 要排序的数组
* @return {Array} 排序后的数组
*/
function buble(ary){
// 外层循环,表示比较多少轮,每轮找出一个最大的数,当找出length-1个最大的数时就排完了
for(let i=0; i<ary.length-1; i++){
// 内层循环,表示剩余的数需要比较多少次
// 第一轮(i=0)还没比,找出了0个最大的数,需要比较 length-1-0 次
// 第二轮(i=1),找出了1个最大的数,需要比较 length-1-1 次
// 第i+1轮(i),找出了i个最大的数,需要比较 length-1-i 次
for(let j=0; j<ary.length-1 -i; j++){
// 如果ary[j]大于ary[j+1],交换
if(ary[j]>ary[j+1]){
[ary[j], ary[j+1]] = [ary[j+1], ary[j]]
}
}
}
return ary
}
效果图示:
二、插入排序
想象抓扑克牌,准备一个空的左手,抓第一张牌,以后抓的每张牌,从后往前插入。抓到的 牌A 和 手中的 牌B 比较,插入规则是:,若A比B大,则将A插入到B后并停止比较;若A比B小,则再往前找,当还是比第一张牌小时,则插入到最前面。
插入排序代码:
/**
* 插入排序,从小到大
* @param {Array} ary 要排序的数组
* @return {Array} 排序后的数组
*/
function insert(ary){
// 准备的左手,并先插入第一张牌
let handle = [ary[0]]
// 循环剩下的牌,设其为抓到的牌A
for(let i=1; i<ary.length; i++){
let A = ary[i]
// 循环手中的牌,从后往前插,设其为手中的牌B
for(let j=handle.length-1; j>=0; j--){
let B = handle[j]
// 若A大于B,则插入到B的后面
if(A>B){
handle.splice(j+1, 0, A) // splice方法是插入到j+1的前面,即B索引位置j的后面
break // 找到插入位置了,需要结束往前插入
}
// 若比第一个元素都小,则插入到最前面
if(j==0){
handle.unshift(A) // 此时使用,handle.splice(0, 0, A)也可以实现相同效果
}
}
}
return handle
}
效果图示:
三、快速排序
需要用到递归,递归就是在函数中自己调用自己。
一个简单的递归例子:
// 求1-10的和,最简单的方式是写个循环,也可以使用递归
function fn(n){
if(n>10) return 0
return n + fn(n+1)
// 1+fn(2)
// 1+2+fn(3)
// 1+2+3+fn(4)
// 1+2+3+4+5+6+7+8+9+10+fn(11)
// 1+2+3+4+5+6+7+8+9+10+0
}
fn(1)
快速排序代码:
/**
* 快速排序,从小到大
* @param {Array} ary 要排序的数组
* @return {Array} 排序后的数组
*/
function quick(ary){
// 4.递归终止条件:当数组没有元素或者只有一个元素时,就没必要再排序了
if(ary.length<=1){
return ary
}
// 1.先挑出中间位置的元素,并从原来数组中删除
let middleIndex = Math.floor(ary.length/2)
let middleValue = ary.splice(middleIndex, 1)[0]
// 2.准备左右两个新数组,循环原数组,比中间元素小的放左边数组,比中间元素大的放右边数组
let leftAry = [], rightAry = []
for(let i=0; i<ary.length; i++){
let item = ary[i]
if(item<middleValue){
leftAry.push(item)
}else{
rightAry.push(item)
}
}
// 3.递归对左右两个数组排序,将结果拼接成:左边数组+中间元素+右边数组,并返回
return quick(leftAry).concat(middleValue, quick(rightAry))
}