三大经典排序算法
- 冒泡排序
- 插入排序
- 快速排序
首先,复习一下数组的基础知识
- arr.push()向数组尾部插入元素,返回新数组的长度
- arr.unshift()向数组头部插入元素,返回新数组的长度
- arr.pop()从数组尾部删除元素,返回被删除的元素
- arr.shift()从数组头部删除元素,返回被删除的元素
- arr.splice(m,n)从数组下标m开始删除n个元素,返回被删除的元素组成的数组,原数组被改变
- arr.slice(start,end)删除数组下标start到end(不含)的元素,返回被删除的元素组成的数组,原数组不变
- arr.concat()实现数组拼接,返回拼接后的新数组,原数组arr不变
- arr.sort()实现数组排序
- arr.sort()不传递参数的情况下,只能处理10以内的排序,即按照第一个字符进行排序
- arr.sort()传递参数的情况下,可以实现正常大小的排序
- 升序:arr.sort((a,b) => a-b)
- 降序:arr.sort((a,b) => b-a)
一、冒泡排序
参考生活中的冒泡现象:大泡泡在上面,小泡泡在下面(浮力的作用)
核心思想:让数组中的当前项和后一项进行比较,如果当前项比后一项大,则两项交换位置(让大的靠后)即可。
二、插入排序
三、快速排序
核心思想:
- 找到中间项(一般向下取整,如:Math.floor(2.5) = 2)
- 把它从原来的数组中移除
- 获取这一项的结果即为中间项的值
- 准备一个左边数组,再准备一个右边数组
- 让拿出来的每一项和中间项继续比较,比中间项小的放左边,比中间项大的放右边
- 每一边继续不断重复上述操作(递归)
- 最后拼接:左边+中间项+右边 注意:结束递归(当arr中小于等于一项的时候则不用处理)
四、手写三大经典排序算法
<script>
let arr = [10,98,5,9,3,45,65,5,54,1] // 待排序数组
// 方法一:冒泡排序
function bubble (arr) {
if (arr.length <= 1) {
return arr
}
for (let i = 0; i < arr.length - 1; i++) { // 比较的轮数
for (let j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j+1]) {
[arr[j], arr[j+1]] = [arr[j+1], arr[j]]
}
}
}
return arr
}
console.log('冒泡排序:', bubble(arr))
// 方法二:插入排序
function insert (arr) {
if (arr.length <= 1) {
return arr
}
let newArr = []
newArr.push(arr[0])
for(let i = 1; i < arr.length; i++) {
for(j=newArr.length - 1; j>=0; j--) {
if (arr[i] > newArr[j]) {
newArr.splice(j+1, 0, arr[i])
}
if (j === 0) {
newArr.unshift(arr[i])
}
}
}
return arr
}
console.log('插入排序:', insert(arr))
// 方法三:快速排序
function quick (arr) {
if (arr.length <= 1) {
return arr
}
let middleIndex = Math.floor(arr.length / 2) // 中间数的下标
let middle = arr.splice(middleIndex, 1)[0] // 取出中间数的值并将中间数从原数组中移除
let left = [], right = []
for(let i = 0; i < arr.length; i++) {
// arr[i] < middle ? left.push(arr[i]) : right.push(arr[i])
if (arr[i] <= middle) { // 注意这里是<=,否则相等元素会丢失
left.push(arr[i])
}
if (arr[i] > middle) {
right.push(arr[i])
}
}
return quick(left).concat(middle).concat(quick(right))
}
console.log('快速排序:', quick(arr))
</script>
输出结果:
冒泡排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]
插入排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]
快速排序: (10) [1, 3, 5, 5, 9, 10, 45, 54, 65, 98]