JavaScript如何实现十大排序算法

发布时间:2022-08-04 14:18:10 作者:iii
来源:亿速云 阅读:154

JavaScript如何实现十大排序算法

排序算法是计算机科学中最基本且重要的算法之一。排序算法的目的是将一组数据按照特定的顺序进行排列。常见的排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序和基数排序。本文将详细介绍如何使用JavaScript实现这十大排序算法,并分析它们的时间复杂度和空间复杂度。

1. 冒泡排序(Bubble Sort)

冒泡排序是一种简单的排序算法。它重复地遍历要排序的列表,比较相邻的元素并交换它们的位置,直到没有需要交换的元素为止。

1.1 算法步骤

  1. 从列表的第一个元素开始,比较相邻的两个元素。
  2. 如果前一个元素大于后一个元素,则交换它们的位置。
  3. 对每一对相邻元素重复上述步骤,直到列表末尾。
  4. 重复上述步骤,直到没有需要交换的元素。

1.2 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;
}

1.3 复杂度分析

2. 选择排序(Selection Sort)

选择排序是一种简单直观的排序算法。它的工作原理是每次从未排序的部分中选择最小(或最大)的元素,放到已排序部分的末尾。

2.1 算法步骤

  1. 在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置。
  2. 从剩余未排序元素中继续寻找最小(或最大)元素,放到已排序序列的末尾。
  3. 重复上述步骤,直到所有元素均排序完毕。

2.2 JavaScript实现

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;
}

2.3 复杂度分析

3. 插入排序(Insertion Sort)

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

3.1 算法步骤

  1. 从第一个元素开始,该元素可以认为已经被排序。
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描。
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置。
  4. 重复步骤3,直到找到已排序的元素小于或等于新元素的位置。
  5. 将新元素插入到该位置后。
  6. 重复步骤2~5。

3.2 JavaScript实现

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;
}

3.3 复杂度分析

4. 希尔排序(Shell Sort)

希尔排序是插入排序的一种高效改进版本,也称为缩小增量排序。它通过将原始列表分成若干子列表来进行排序,每个子列表使用插入排序。

4.1 算法步骤

  1. 选择一个增量序列t1, t2, …, tk,其中ti > tj, tk = 1。
  2. 按增量序列个数k,对序列进行k趟排序。
  3. 每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m的子序列,分别对各子表进行直接插入排序。
  4. 仅增量因子为1时,整个序列表来处理,表长度即为整个序列的长度。

4.2 JavaScript实现

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;
}

4.3 复杂度分析

5. 归并排序(Merge Sort)

归并排序是一种分治算法。它将原始列表分成若干子列表,每个子列表是有序的,然后再将有序子列表合并成一个完整的有序列表。

5.1 算法步骤

  1. 将列表分成两个子列表,分别进行排序。
  2. 将两个有序子列表合并成一个有序列表。

5.2 JavaScript实现

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));
}

5.3 复杂度分析

6. 快速排序(Quick Sort)

快速排序是一种分治算法。它通过选择一个“基准”元素,将列表分成两部分,一部分小于基准,一部分大于基准,然后递归地对这两部分进行排序。

6.1 算法步骤

  1. 从列表中选择一个元素作为基准(pivot)。
  2. 将列表分成两部分,一部分小于基准,一部分大于基准。
  3. 递归地对这两部分进行快速排序。

6.2 JavaScript实现

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)];
}

6.3 复杂度分析

7. 堆排序(Heap Sort)

堆排序是一种基于二叉堆的排序算法。它通过构建一个最大堆(或最小堆),然后将堆顶元素与堆的最后一个元素交换,再调整堆,重复这个过程直到整个列表有序。

7.1 算法步骤

  1. 构建一个最大堆(或最小堆)。
  2. 将堆顶元素与堆的最后一个元素交换。
  3. 调整堆,使其重新满足堆的性质。
  4. 重复步骤2~3,直到堆的大小为1。

7.2 JavaScript实现

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);
    }
}

7.3 复杂度分析

8. 计数排序(Counting Sort)

计数排序是一种非比较排序算法。它通过统计每个元素的出现次数,然后根据统计结果将元素放回正确的位置。

8.1 算法步骤

  1. 统计每个元素的出现次数。
  2. 根据统计结果,将元素放回正确的位置。

8.2 JavaScript实现

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;
}

8.3 复杂度分析

9. 桶排序(Bucket Sort)

桶排序是一种分布式排序算法。它将元素分到有限数量的桶中,每个桶再分别排序(通常使用其他排序算法或递归地使用桶排序)。

9.1 算法步骤

  1. 设置一个定量的数组当作空桶。
  2. 遍历输入数据,并且把数据一个一个放到对应的桶里去。
  3. 对每个不是空的桶进行排序。
  4. 从不是空的桶里把排好序的数据拼接起来。

9.2 JavaScript实现

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;
}

9.3 复杂度分析

10. 基数排序(Radix Sort)

基数排序是一种非比较排序算法。它通过将整数按位数切割成不同的数字,然后按每个位数分别比较。

10.1 算法步骤

  1. 取得数组中的最大数,并取得位数。
  2. 从最低位开始,依次进行一次排序。
  3. 从最低位排序一直到最高位排序完成以后, 数列就变成一个有序序列。

10.2 JavaScript实现

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;
}

10.3 复杂度分析

总结

本文详细介绍了十大排序算法的JavaScript实现,并分析了它们的时间复杂度和空间复杂度。不同的排序算法适用于不同的场景,选择合适的排序算法可以显著提高程序的效率。希望本文能帮助你更好地理解和应用这些排序算法。

推荐阅读:
  1. 十大经典排序算法的算法描述和代码实现
  2. 十大内排序算法总结比较

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript

上一篇:JavaScript数组操作方法有哪些

下一篇:JavaScript中数组常用的迭代处理方法有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》