文章目录
- 快速排序
- 归并排序
排序有很多种算法,常听的十大排序有:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序、希尔排序、计数排序、基数排序、桶排序。
这里只介绍两个常用的算法。
排序:
- 快速排序
- 归并排序
你可能想知道什么时候该用哪个:
快速排序使用场景:快速排序平均时间复杂度为O(n log n),最坏情况下为O(n²),不太稳定,但优点是不占用额外空间,快速排序为原地排序。 在实践中,快速排序通常优于其他时间复杂度为 O(n log n) 的算法,
归并排序使用场景:时间复杂度为O(n log n)。无论情况好坏都相对稳定。优点是稳定,但需要占用额外的O(n)空间。
快速排序
思路:选择一个基准元素,将所有小于基准的元素放置在其左侧,将所有大于基准的元素放置在其右侧。这种操作称为“分区”。然后分别对基准左侧和右侧的两个子元素执行相同的操作。
现在开始快速排序的基本步骤思路:
1: 数据数组
2: 选择基准
3: 设置左边界和右边界
4: 如果右边界小于基准值,则调换左边界和右边界的值,接着左边界i++,随后右边界j++(如果循环未结束)。否则仅j++
如果不理解,请仔细阅读第四标题的内容:如果右边界小于基准值,则调换左边界和右边界的值,接着左边界i++,随后右边界j++(如果循环未结束)。否则仅j++
5: 循环结束后,交换左边界和基准的值
6: 根据基准,截取两部分的值
7:将左右两部分分别执行 1-6 的步骤
JavaScript实现代码:
function myQuickSort(array, left = 0, right = array.length - 1) {
if (left < right) {
// 获取分区后枢轴的位置
let pivotIndex = pivotIndexMeth(array, left, right)
// 递归调用
myQuickSort(array, left, pivotIndex - 1)
// 递归调用
myQuickSort(array, pivotIndex + 1, right)
}
return array
}
function pivotIndexMeth(array, left, right) {
// 使用最右边的元素作为枢轴
let pivot = array[right]
// 从左边开始
let i = left;
// 遍历数组
for (let j = left; j < right; j++) {
// 如果元素小于枢轴,就交换它和当前的“i”元素
if (array[j] < pivot) {
[array[i], array[j]] = [array[j], array[i]]
i++
}
}
// 最后,将枢轴放置在正确的位置
[array[i], array[right]] = [array[right], array[i]]
// 返回枢轴的位置
return i;
}
console.log(myQuickSort([7, 2, 3, 1, 6, 8, 4, 5]))
归并排序
思路:将一个大列表分成两个较小的子列表,然后分别对两个子列表进行排序,最后将两个已排序的子列表合并为一个完整的排序列表。
现在开始归并排序的基本步骤思路:
1: 数据数组
2: 求出中心点,分割数据
3: 将分割后的数据继续分割
4: 将分割后的数据继续分割
5: 直至分割成一个单位长度的数组之后,进行大小对比排序
JavaScript实现代码:
function myMergeSort(array) {
// 获取数组长度
let len = array.length;
// 如果数组长度小于2,返回
if (len < 2) {
return array;
}
// 获取中间值
let middle = Math.floor(len / 2)
// 获取左边的数组
let left = array.slice(0, middle)
// 获取右边的数组
let right = array.slice(middle)
// 递归调用
return merge(myMergeSort(left), myMergeSort(right))
}
function merge(left, right) {
// 定义一个数组
let result = [];
// 如果左边和右边的数组都有值
while (left.length && right.length) {
// 如果左边的第一个值小于右边的第一个值
if (left[0] < right[0]) {
// 将左边的第一个值放入数组
result.push(left.shift())
} else {
// 将右边的第一个值放入数组
result.push(right.shift())
}
}
// 如果左边的数组有值
while (left.length) {
result.push(left.shift())
}
// 如果右边的数组有值
while (right.length) {
result.push(right.shift())
}
return result;
}
console.log(myMergeSort([7, 2, 3, 1, 6, 8, 4, 5]))
如果解释有误或需要补充,感谢您指正。