1.冒泡排序
实现思路:将数组中n个元素经过n-1轮的比较,每一轮的比较要在未排序部分中找出最大的数移动到数组末尾(这里的末尾并非是数组最后一个元素),同时每当比较完一轮,下一轮比较区间应该缩小。
Array.prototype.bubbleSort = function () {
for (let i = 0; i < this.length - 1; i++) {
for (let j = 0; j < this.length - 1 - i; j++) {
// 前者大于后者则进行交换
if (this[j] > this[j + 1]) {
let temp = this[j]
this[j] = this[j + 1]
this[j + 1] = temp
}
}
}
return this
}
2.选择排序
实现思路:将数组中n个元素经过n-1轮比较,第i轮比较会在未排序的元素中找到最小值并记录其索引,与数组索引为i的元素进行交换,经过n-1轮循环即可实现排序。
Array.prototype.selectionSort = function () {
for (let i = 0; i < this.length; i++) {
let index = i
for (let j = i + 1; j < this.length; j++) {
// 找到最小值对应的索引
if (this[index] > this[j]) {
index = j
}
}
let temp = this[i]
this[i] = this[index]
this[index] = temp
}
return this
}
3.插入排序
实现思路:从数组索引为1开始遍历,从该位置往前比较,找到比该元素大的元素时则交换位置,下一轮循环就从索引为2开始,重复以上过程。将开始遍历的位置记作为j,还需要注意[1,j-1]之间元素,若有错位也需要交换位置。设数组有n个元素,那么经过n轮循环即可实现排序。
Array.prototype.insertSort = function () {
for (let i = 1; i < this.length; i++) {
let j = i
let temp = this[i]
while (j > 0) {
if (temp < this[j - 1]) {
this[j] = this[j - 1]
} else {
break
}
j--
}
this[j] = temp
}
return this
}
4.归并排序
实现思路:将整个数组分成两半,再把子数组分成两半,直至数组分成只包含单个数才结束,然后开始有序地合并元素。
Array.prototype.mergerSort = function () {
const help = (arr) => {
// 数组元素个数为1时 不需要再切割 直接返回
if (arr.length === 1) return arr
const mid = Math.floor(arr.length / 2)
const left = arr.slice(0, mid)
const right = arr.slice(mid, arr.length)
const leftRes = help(left)
const rightRes = help(right)
const res = []
while (leftRes.length || rightRes.length) {
if (leftRes.length && rightRes.length) {
// 左右数组均不为空 小的先被push
res.push(leftRes[0] < rightRes[0] ? leftRes.shift() : rightRes.shift())
} else if (leftRes.length) {
// 左边数组不为空 右边数组为空
res.push(leftRes.shift())
} else if (rightRes) {
// 右边数组不为空 左边数组为空
res.push(rightRes.shift())
}
}
return res
}
const res = help(this)
return res
}
步骤解析:这里画图不知道怎么好表达,所以就用文字来描述一下过程。
- 执行help(this),left=[3,2], right=[4,1],然后执行help(left)即help([3,2])。
- 执行help([3,2])时,left=[3], right=[2],然后执行help(left)即help([3])。
- 执行help([3])时,经过判断执行return操作,所以对于执行help([3,2])这一次操作来说,其leftRes=[3]。
- 对于执行help([3,2])这一步,const leftRes = help([3])已执行完,此时应该开始执行help(right)即help([2])。
- 执行help([2])时,经过判断执行return操作,所以对于help([3,2])这一次操作来说,其rightRes=[2]。
- 此时对于help([3,2])来说,还剩余while循环及其后面的代码还没执行,所以此时开始执行while循环合并leftRes、rightRes到变量res中,最终res = [2, 3]。这里的res被return,所以对于help(this)这一步操作,其leftRes=res=[2,3]。
- 对于help(this)来说,其leftRes已经拿到了,准备开始执行const rightRes = help([4,1]),剩余过程其实上面一样,这里就不再叙述了...
总结:leftRes拿到就是左数组经过排序的数组,rightRes拿到的就是右数组经过排序的数组,再通过while循环从小到大依次合并即可。
5.快速排序
实现思路:在数组中选择一个元素作为基准,小于该基准值的元素和大于该基准值的元素分别放到两个数组里,再对子数组进行递归操作,直到子数组所有元素都是有序的。
Array.prototype.quickSort = function () {
const help = (arr) => {
if (arr.length <= 1) {
return arr
}
const left = []
const right = []
const base = arr[0]
for (let i = 1; i < arr.length; i++) {
if (arr[i] < base) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return [...help(left), base, ...help(right)]
}
return help(this)
}
最后
如果大家看到哪里有错误希望指出,感谢各位大佬指教!(抱拳)