探索基础排序和进阶排序算法
排序算法是计算机科学中的重要基础知识,对于处理大量数据的应用来说尤为关键。在本文中,我们将探索几种常见的基础排序算法和进阶排序算法,包括冒泡排序、选择排序、插入排序、快速排序和归并排序。通过深入了解它们的原理和实现方法,我们可以更好地理解排序算法的不同思想和应用场景。
冒泡排序
冒泡排序是一种简单直观的排序算法,它通过相邻元素的比较和交换来实现排序。具体实现步骤如下:
- 从第一个元素开始,依次比较相邻的两个元素。
- 如果前一个元素大于后一个元素,则交换它们的位置。
- 对整个序列重复上述操作,直到序列有序为止。
冒泡排序的时间复杂度为O(n^2),适用于数据量较小的情况。
function bubbleSort(arr) {
const len = arr.length;
for (let i = 0; i < len - 1; i++) {
for (let j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 交换相邻两个元素的位置
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
// 示例用法
const nums = [5, 3, 8, 4, 2];
console.log(bubbleSort(nums)); // 输出:[2, 3, 4, 5, 8]
选择排序
选择排序是一种简单直观的排序算法,它通过每次选择未排序部分的最小(或最大)元素来实现排序。具体实现步骤如下:
- 在未排序部分选择最小(或最大)元素。
- 将该元素与未排序部分的第一个元素交换位置。
- 对未排序部分重复上述操作,直到整个序列有序为止。 选择排序的时间复杂度为O(n^2),与冒泡排序类似,适用于数据量较小的情况。
function selectionSort(arr) {
var len = arr.length;
var minIndex, temp;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
var array = [64, 25, 12, 22, 11];
console.log(selectionSort(array));
插入排序
插入排序是一种简单直观的排序算法,它通过将待排序元素插入到已排序部分的正确位置来实现排序。具体实现步骤如下:
- 将第一个元素视为已排序部分。
- 依次将后续元素插入到已排序部分的正确位置。
- 对整个序列重复上述操作,直到序列有序为止。
插入排序的时间复杂度为O(n^2),但在某些特定情况下,插入排序的性能可能优于冒泡排序和选择排序。
function insertionSort(arr) {
var len = arr.length;
for (var i = 1; i < len; i++) {
var current = arr[i];
var j = i - 1;
while (j >= 0 && arr[j] > current) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = current;
}
return arr;
}
var array = [64, 25, 12, 22, 11];
console.log(insertionSort(array));
快速排序
快速排序是一种基于分治策略的排序算法,它通过每次选择一个基准元素,将待排序数组分割成两部分,然后递归地对这两部分进行排序,最终得到有序数组。快速排序的时间复杂度为O(nlogn),在平均情况下表现良好,但在最坏情况下可能达到O(n^2)。 JavaScript中的快速排序算法示例如下:
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
}
var array = [64, 25, 12, 22, 11];
console.log(quickSort(array));
这段代码实现了快速排序算法。快速排序的基本思想是,选择一个基准元素,将小于基准的元素放到基准的左边,大于基准的元素放到基准的右边,再对左右两个部分递归地进行快速排序,最终完成排序。
以上代码中,quickSort
函数接受一个数组作为参数,并返回排序后的数组。在函数内部,首先判断数组长度是否小于等于1,如果是,则直接返回原数组。否则,选择一个基准元素(这里选择中间位置的元素),然后遍历数组,将小于基准的元素放入左侧数组,大于基准的元素放入右侧数组。最后,通过递归调用quickSort
函数对左右两个数组进行排序,并将结果合并。
归并排序
归并排序是一种基于分治策略的排序算法,它通过将待排序数组递归地分成更小的子数组,然后不断地将这些子数组合并成较大的有序数组,直到最终得到完全有序的数组。归并排序的时间复杂度为O(nlogn),而且在任何情况下都能保证稳定性。 JavaScript中的归并排序算法示例如下:
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
let result = [];
let i = 0;
let j = 0;
while (i < left.length && j < right.length) {
if (left[i] < right[j]) {
result.push(left[i]);
i++;
} else {
result.push(right[j]);
j++;
}
}
return result.concat(left.slice(i)).concat(right.slice(j));
}
var array = [64, 25, 12, 22, 11];
console.log(mergeSort(array));
这段代码实现了归并排序算法。归并排序的基本思想是将待排序的数组不断地拆分成更小的子数组,然后再将这些子数组进行合并操作,最终完成排序。
以上代码中,mergeSort
函数接受一个数组作为参数,并返回排序后的数组。在函数内部,首先判断数组长度是否小于等于1,如果是,则直接返回原数组。否则,找到中间位置,并将数组分割成左右两个部分。接着,通过递归调用mergeSort
函数对左右两个部分进行排序。最后,调用merge
函数将排序好的左右两个部分进行合并。
merge
函数用于将两个有序数组合并成一个有序数组。在函数内部,通过比较左右两个数组的元素大小,将较小的元素依次放入结果数组中。最后,将剩余的元素直接添加到结果数组的末尾。
总结: 本文介绍了几种常见的基础排序算法和进阶排序算法。基础排序算法包括冒泡排序、选择排序和插入排序,它们简单直观但相对低效。进阶排序算法包括快速排序和归并排序,它们通过分治策略和合并操作实现高效的排序。在实际应用中,我们可以根据具体问题的要求选择合适的排序算法。
转载自:https://juejin.cn/post/7310024732354150437