您好,登录后才能下订单哦!
排序算法是计算机科学中最基本且重要的算法之一。排序算法的目的是将一组数据按照特定的顺序进行排列。常见的排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序和基数排序。本文将详细介绍如何使用JavaScript实现这十大排序算法,并分析它们的时间复杂度和空间复杂度。
冒泡排序是一种简单的排序算法。它重复地遍历要排序的列表,比较相邻的元素并交换它们的位置,直到没有需要交换的元素为止。
function bubbleSort(arr) {
let 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;
}
选择排序是一种简单直观的排序算法。它的工作原理是每次从未排序的部分中选择最小(或最大)的元素,放到已排序部分的末尾。
function selectionSort(arr) {
let len = arr.length;
for (let i = 0; i < len - 1; i++) {
let minIndex = i;
for (let j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
return arr;
}
插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
function insertionSort(arr) {
let len = arr.length;
for (let i = 1; i < len; i++) {
let key = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
return arr;
}
希尔排序是插入排序的一种高效改进版本,也称为缩小增量排序。它通过将原始列表分成若干子列表来进行排序,每个子列表使用插入排序。
function shellSort(arr) {
let len = arr.length;
let gap = Math.floor(len / 2);
while (gap > 0) {
for (let i = gap; i < len; i++) {
let temp = arr[i];
let j = i;
while (j >= gap && arr[j - gap] > temp) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = temp;
}
gap = Math.floor(gap / 2);
}
return arr;
}
归并排序是一种分治算法。它将原始列表分成若干子列表,每个子列表是有序的,然后再将有序子列表合并成一个完整的有序列表。
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
let result = [];
let i = 0, 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));
}
快速排序是一种分治算法。它通过选择一个“基准”元素,将列表分成两部分,一部分小于基准,一部分大于基准,然后递归地对这两部分进行排序。
function quickSort(arr) {
if (arr.length <= 1) {
return arr;
}
const pivot = arr[0];
const left = [];
const right = [];
for (let i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return [...quickSort(left), pivot, ...quickSort(right)];
}
堆排序是一种基于二叉堆的排序算法。它通过构建一个最大堆(或最小堆),然后将堆顶元素与堆的最后一个元素交换,再调整堆,重复这个过程直到整个列表有序。
function heapSort(arr) {
let len = arr.length;
for (let i = Math.floor(len / 2) - 1; i >= 0; i--) {
heapify(arr, len, i);
}
for (let i = len - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
heapify(arr, i, 0);
}
return arr;
}
function heapify(arr, len, i) {
let largest = i;
let left = 2 * i + 1;
let right = 2 * i + 2;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(arr, len, largest);
}
}
计数排序是一种非比较排序算法。它通过统计每个元素的出现次数,然后根据统计结果将元素放回正确的位置。
function countingSort(arr) {
let max = Math.max(...arr);
let count = new Array(max + 1).fill(0);
for (let num of arr) {
count[num]++;
}
let index = 0;
for (let i = 0; i <= max; i++) {
while (count[i] > 0) {
arr[index++] = i;
count[i]--;
}
}
return arr;
}
桶排序是一种分布式排序算法。它将元素分到有限数量的桶中,每个桶再分别排序(通常使用其他排序算法或递归地使用桶排序)。
function bucketSort(arr, bucketSize = 5) {
if (arr.length === 0) {
return arr;
}
let min = Math.min(...arr);
let max = Math.max(...arr);
let bucketCount = Math.floor((max - min) / bucketSize) + 1;
let buckets = new Array(bucketCount);
for (let i = 0; i < buckets.length; i++) {
buckets[i] = [];
}
for (let i = 0; i < arr.length; i++) {
let bucketIndex = Math.floor((arr[i] - min) / bucketSize);
buckets[bucketIndex].push(arr[i]);
}
arr.length = 0;
for (let i = 0; i < buckets.length; i++) {
insertionSort(buckets[i]);
for (let j = 0; j < buckets[i].length; j++) {
arr.push(buckets[i][j]);
}
}
return arr;
}
基数排序是一种非比较排序算法。它通过将整数按位数切割成不同的数字,然后按每个位数分别比较。
function radixSort(arr) {
let max = Math.max(...arr);
let maxDigit = String(max).length;
let mod = 10;
let dev = 1;
for (let i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
let counter = new Array(10).fill(0);
for (let j = 0; j < arr.length; j++) {
let bucket = Math.floor((arr[j] % mod) / dev);
counter[bucket]++;
}
for (let j = 1; j < counter.length; j++) {
counter[j] += counter[j - 1];
}
let temp = new Array(arr.length);
for (let j = arr.length - 1; j >= 0; j--) {
let bucket = Math.floor((arr[j] % mod) / dev);
temp[--counter[bucket]] = arr[j];
}
arr = temp;
}
return arr;
}
本文详细介绍了十大排序算法的JavaScript实现,并分析了它们的时间复杂度和空间复杂度。不同的排序算法适用于不同的场景,选择合适的排序算法可以显著提高程序的效率。希望本文能帮助你更好地理解和应用这些排序算法。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。