• 基本排序算法


    1. 冒泡排序(Bubble Sort)

    冒泡排序是一种简单的排序算法,它重复地遍历要排序的列表,一次比较两个元素,如果它们的顺序错误就交换它们。遍历的过程会持续多次,每次遍历都会将未排序部分中的最大元素移动到末尾。

    1. /**
    2. * 冒泡排序
    3. * 遍历数组,对于每个元素,与其后一个元素进行比较,如果前一个元素大于后一个元素,则交换它们的位置
    4. *
    5. * @param arr 要排序的数组
    6. */
    7. function bubbleSort(arr) {
    8. // 获取数组的长度
    9. const n = arr.length;
    10. // 遍历数组
    11. for (let i = 0; i < n; i++) {
    12. // 遍历数组中未排序的部分
    13. for (let j = 0; j < n - i - 1; j++) {
    14. // 如果前一个元素大于后一个元素,则交换它们的位置
    15. if (arr[j] > arr[j + 1]) {
    16. [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
    17. }
    18. }
    19. }
    20. }
    21. // 定义要排序的数组
    22. let arr = [64, 34, 25, 12, 22, 11, 90];
    23. // 调用bubbleSort()函数对数组进行冒泡排序
    24. bubbleSort(arr);
    25. // 输出排序后的数组
    26. console.log("冒泡排序结果:", arr);

    2. 选择排序(Selection Sort)

    选择排序是一种简单直观的排序算法,它首先在未排序的序列中找到最小(或最大)元素,然后将其放到序列的起始位置,接着从剩余的未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。重复这个过程,直到所有元素都排序完毕。

    1. /**
    2. * 选择排序
    3. *遍历数组,找出最小元素的索引,将其与当前元素交换
    4. * @param arr 要排序的数组
    5. */
    6. function selectionSort(arr) {
    7. // 获取数组的长度
    8. const n = arr.length;
    9. // 遍历数组
    10. for (let i = 0; i < n; i++) {
    11. // 找出最小元素的索引
    12. let minIndex = i;
    13. for (let j = i + 1; j < n; j++) {
    14. if (arr[j] < arr[minIndex]) {
    15. minIndex = j;
    16. }
    17. }
    18. // 交换当前元素与最小元素的位置
    19. [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
    20. }
    21. }
    22. // 定义要排序的数组
    23. let arr = [64, 34, 25, 12, 22, 11, 90];
    24. // 调用selectionSort()函数对数组进行选择排序
    25. selectionSort(arr);
    26. // 输出排序后的数组
    27. console.log("选择排序结果:", arr);

    3. 插入排序(Insertion Sort)

    插入排序是一种简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序的数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序每次将一个待排序的元素插入到已排序序列的适当位置,直到全部元素排序完毕。

    1. /**
    2. * 插入排序
    3. *
    4. * @param arr 待排序的数组
    5. */
    6. function insertionSort(arr) {
    7. // 获取数组长度
    8. const n = arr.length;
    9. // 从第二个元素开始遍历
    10. for (let i = 1; i < n; i++) {
    11. // 将当前元素作为待插入的键值
    12. let key = arr[i];
    13. // 从当前元素的前一个元素开始向前遍历
    14. let j = i - 1;
    15. // 当遍历到的元素大于键值并且索引大于等于0时,将遍历到的元素后移一位
    16. while (j >= 0 && arr[j] > key) {
    17. arr[j + 1] = arr[j];
    18. j--;
    19. }
    20. // 将键值插入到正确的位置
    21. arr[j + 1] = key;
    22. }
    23. }
    24. let arr = [64, 34, 25, 12, 22, 11, 90];
    25. insertionSort(arr);
    26. console.log("插入排序结果:", arr);

    4. 归并排序(Merge Sort)

    归并排序是一种分治算法,它将待排序的列表分为两个子序列,分别对两个子序列进行递归排序,然后将两个有序子序列合并成一个有序序列。归并排序的关键在于合并操作,将两个有序序列合并成一个有序序列的过程。

    1. /**
    2. * 使用归并排序算法对数组进行排序
    3. *
    4. * @param arr 需要排序的数组
    5. * @returns 排序后的数组
    6. */
    7. function mergeSort(arr) {
    8. // 如果数组长度小于等于1,则直接返回该数组
    9. if (arr.length <= 1) {
    10. return arr;
    11. }
    12. // 计算数组中间位置
    13. const mid = Math.floor(arr.length / 2);
    14. // 对左半部分进行归并排序
    15. const left = mergeSort(arr.slice(0, mid));
    16. // 对右半部分进行归并排序
    17. const right = mergeSort(arr.slice(mid));
    18. // 合并左右两部分排序后的数组
    19. return merge(left, right);
    20. }
    21. /**
    22. * 合并两个有序数组
    23. *
    24. * @param left 左侧有序数组
    25. * @param right 右侧有序数组
    26. * @returns 返回合并后的有序数组
    27. */
    28. function merge(left, right) {
    29. let result = [];
    30. let i = 0;
    31. let j = 0;
    32. // 当左右两个数组都有元素时
    33. while (i < left.length && j < right.length) {
    34. // 将较小的元素添加到结果数组中
    35. if (left[i] < right[j]) {
    36. result.push(left[i]);
    37. i++;
    38. } else {
    39. result.push(right[j]);
    40. j++;
    41. }
    42. }
    43. // 当左数组还有剩余元素时
    44. while (i < left.length) {
    45. result.push(left[i]);
    46. i++;
    47. }
    48. // 当右数组还有剩余元素时
    49. while (j < right.length) {
    50. result.push(right[j]);
    51. j++;
    52. }
    53. // 返回合并后的数组
    54. return result;
    55. }
    56. /**
    57. * 合并两个已排序好的数组,返回一个新数组,新数组也是已排序的
    58. *
    59. * @param left 左侧已排序数组
    60. * @param right 右侧已排序数组
    61. * @returns 返回合并后已排序的新数组
    62. */
    63. function merge(left, right) {
    64. // 创建一个空数组用于存储合并后的结果
    65. let result = [];
    66. // 定义左数组索引
    67. let leftIndex = 0;
    68. // 定义右数组索引
    69. let rightIndex = 0;
    70. // 当左右两个数组都还有元素时执行循环
    71. while (leftIndex < left.length && rightIndex < right.length) {
    72. // 如果左数组当前元素小于右数组当前元素
    73. if (left[leftIndex] < right[rightIndex]) {
    74. // 将左数组当前元素添加到结果数组中
    75. result.push(left[leftIndex]);
    76. // 左数组索引加1
    77. leftIndex++;
    78. } else {
    79. // 否则将右数组当前元素添加到结果数组中
    80. result.push(right[rightIndex]);
    81. // 右数组索引加1
    82. rightIndex++;
    83. }
    84. }
    85. // 循环结束后,将左数组剩余的元素添加到结果数组中
    86. // 使用slice方法从leftIndex开始截取左数组剩余的元素
    87. return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
    88. }
    89. let arr = [64, 34, 25, 12, 22, 11, 90];
    90. arr = mergeSort(arr);
    91. console.log("归并排序结果:", arr);

    5. 快速排序(Quick Sort)

    快速排序是一种分治算法,它选择一个基准元素,将列表分为两部分,使得左边的元素都小于基准元素,右边的元素都大于基准元素,然后对左右两部分递归地进行快速排序。快速排序的关键在于分区操作,将列表中的元素按照基准元素进行分区。

    1. /**
    2. * 快速排序函数
    3. *
    4. * @param arr 待排序数组
    5. * @returns 排序后的数组
    6. */
    7. function quickSort(arr) {
    8. // 如果数组长度小于等于1,则直接返回数组
    9. if (arr.length <= 1) {
    10. return arr;
    11. }
    12. // 选取数组最后一个元素作为枢轴
    13. const pivot = arr[arr.length - 1];
    14. // 初始化左、右两个空数组
    15. const left = [];
    16. const right = [];
    17. // 遍历数组,将小于枢轴的元素放入左数组,大于等于枢轴的元素放入右数组
    18. for (let i = 0; i < arr.length - 1; i++) {
    19. if (arr[i] < pivot) {
    20. left.push(arr[i]);
    21. } else {
    22. right.push(arr[i]);
    23. }
    24. }
    25. // 对左、右两个数组进行递归排序,并将排序结果和枢轴拼接起来返回
    26. return quickSort(left).concat(pivot, quickSort(right));
    27. }
    28. let arr = [64, 34, 25, 12, 22, 11, 90];
    29. arr = quickSort(arr);
    30. console.log("快速排序结果:", arr);

    6. 堆排序(Heap Sort)

    堆排序利用了堆这种数据结构的特性,将待排序的列表构建成一个最大堆或最小堆,然后将堆顶元素与堆的最后一个元素交换,然后调整堆,使得剩余元素仍构成一个最大堆或最小堆,依次类推,直到所有元素都排序完毕。

    1. /**
    2. * 对给定的数组进行堆排序
    3. *
    4. * @param arr 待排序的数组
    5. */
    6. function heapSort(arr) {
    7. const n = arr.length; // 获取数组的长度
    8. // 从最后一个非叶子节点开始,向上到根节点,逐个进行堆化
    9. for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
    10. heapify(arr, n, i);
    11. }
    12. // 从堆顶开始,将最大值与堆尾元素交换,然后重新堆化剩下的元素
    13. for (let i = n - 1; i > 0; i--) {
    14. [arr[0], arr[i]] = [arr[i], arr[0]]; // 交换堆顶元素和当前元素
    15. heapify(arr, i, 0); // 重新对剩下的元素进行堆化
    16. }
    17. }
    18. /**
    19. * 将数组 arr 中以索引 i 为根节点的子树堆化
    20. *
    21. * @param arr 数组
    22. * @param n 数组长度
    23. * @param i 当前节点索引
    24. */
    25. function heapify(arr, n, i) {
    26. let largest = i; // 初始化最大值为当前节点
    27. const left = 2 * i + 1; // 左子节点索引
    28. const right = 2 * i + 2; // 右子节点索引
    29. // 如果左子节点大于当前最大值,则更新最大值
    30. if (left < n && arr[left] > arr[largest]) {
    31. largest = left;
    32. }
    33. // 如果右子节点大于当前最大值,则更新最大值
    34. if (right < n && arr[right] > arr[largest]) {
    35. largest = right;
    36. }
    37. // 如果最大值不是当前节点,则交换它们,并继续堆化子树
    38. if (largest !== i) {
    39. [arr[i], arr[largest]] = [arr[largest], arr[i]]; // 交换节点
    40. heapify(arr, n, largest); // 堆化子树
    41. }
    42. }
    43. // 示例数组
    44. let arr = [64, 34, 25, 12, 22, 11, 90];
    45. // 对示例数组进行堆排序
    46. heapSort(arr);
    47. // 输出排序后的结果
    48. console.log("堆排序结果:", arr); // 输出:[11, 12, 22, 25, 34, 64, 90]

  • 相关阅读:
    SQL: MAX Function
    JKChangeCapture swift 版本的捕捉属性变化的工具
    SQL 常见函数整理 _ ROUND() 四舍五入函数
    Vue.js 路由时用于提高应用程序性能
    【算法】判断一个数是否是质数的四种常用方法
    高项 06 项目进度管理
    R语言高级数据管理
    C语言const修饰指针场景demo
    HTTP1.0和HTTP2.0的区别
    使用 Vue 3 插件(Plugin)实现 OIDC 登录和修改密码(OIDC 系统以 Keycloak 为例)
  • 原文地址:https://blog.csdn.net/xhc6666/article/details/136618381