数据结构基础之排序算法

这篇具有很好参考价值的文章主要介绍了数据结构基础之排序算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在数据结构中,常见的排序算法有以下几种:

  1. 冒泡排序(Bubble Sort):通过比较相邻元素并交换它们的位置,每轮将最大(或最小)的元素冒泡到末尾,重复执行直到排序完成。
function bubbleSort(arr) {
  const n = arr.length;
  for (let i = 0; i < n - 1; i++) {
    for (let j = 0; j < n - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(bubbleSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:简单易懂,但对于大型数据集效率较低。
时间复杂度:
最优情况:O(n)(当数组已经排序好时)。
平均情况:O(n^2)。
最坏情况:O(n^2)。

  1. 插入排序(Insertion Sort):将数组分为已排序和未排序两部分,每次从未排序部分选择一个元素插入到已排序部分的正确位置,重复执行直到排序完成。
function insertionSort(arr) {
  const n = arr.length;
  for (let i = 1; i < n; 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;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(insertionSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:适用于小型数据集和部分有序数组。
时间复杂度:
最优情况:O(n)(当数组已经排序好时)。
平均情况:O(n^2)。
最坏情况:O(n^2)。

  1. 选择排序(Selection Sort):每轮从未排序部分选择最小(或最大)的元素,将其与未排序部分的首元素交换,重复执行直到排序完成。
function selectionSort(arr) {
  const n = arr.length;
  for (let i = 0; i < n - 1; i++) {
    let minIdx = i;
    for (let j = i + 1; j < n; j++) {
      if (arr[j] < arr[minIdx]) {
        minIdx = j;
      }
    }
    [arr[i], arr[minIdx]] = [arr[minIdx], arr[i]];
  }
  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(selectionSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:简单易懂,但对于大型数据集效率较低。
时间复杂度:
最优情况:O(n^2)。
平均情况:O(n^2)。
最坏情况:O(n^2)。

  1. 快速排序(Quick Sort):通过选取一个基准元素,将数组分成比基准元素小和大的两部分,然后递归地对两部分进行排序。
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)];
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(quickSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:高效且被广泛使用的排序算法。
时间复杂度:
最优情况:O(n log n)。
平均情况:O(n log n)。
最坏情况:O(n^2)。

  1. 归并排序(Merge Sort):将数组不断分割成较小的子数组,然后再将子数组按顺序合并,重复执行直到排序完成。
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) {
  const mergedArr = [];
  let leftIdx = 0;
  let rightIdx = 0;
  while (leftIdx < left.length && rightIdx < right.length) {
    if (left[leftIdx] < right[rightIdx]) {
      mergedArr.push(left[leftIdx]);
      leftIdx++;
    } else {
      mergedArr.push(right[rightIdx]);
      rightIdx++;
    }
  }
  return [...mergedArr, ...left.slice(leftIdx), ...right.slice(rightIdx)];
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(mergeSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:稳定的排序算法,适用于大型数据集。
时间复杂度:
最优情况:O(n log n)。
平均情况:O(n log n)。
最坏情况:O(n log n)。

  1. 堆排序(Heap Sort):利用二叉堆(最大堆或最小堆)的特性进行排序,将堆顶元素与最后一个元素交换,然后重建堆,重复执行直到排序完成。
function heapSort(arr) {
  const n = arr.length;
  for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
    heapify(arr, n, i);
  }
  for (let i = n - 1; i >= 0; i--) {
    [arr[0], arr[i]] = [arr[i], arr[0]];
    heapify(arr, i, 0);
  }
  return arr;
}

function heapify(arr, n, i) {
  let largest = i;
  const left = 2 * i + 1;
  const right = 2 * i + 2;
  if (left < n && arr[left] > arr[largest]) {
    largest = left;
  }
  if (right < n && arr[right] > arr[largest]) {
    largest = right;
  }
  if (largest !== i) {
    [arr[i], arr[largest]] = [arr[largest], arr[i]];
    heapify(arr, n, largest);
  }
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(heapSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:高效的原地排序算法。
时间复杂度:
最优情况:O(n log n)。
平均情况:O(n log n)。
最坏情况:O(n log n)。

  1. 希尔排序(Shell Sort):是插入排序的一种改进算法,通过分组进行插入排序,逐渐缩小分组间隔,直到分组间隔为1。
function shellSort(arr) {
  const n = arr.length;
  for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
    for (let i = gap; i < n; i++) {
      let temp = arr[i];
      let j;
      for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
        arr[j] = arr[j - gap];
      }
      arr[j] = temp;
    }
  }
  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(shellSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:插入排序的改进版本,适用于中等大小的数据集。
时间复杂度:
最优情况:O(n log^2 n)(取决于步长序列)。
平均情况:取决于步长序列。
最坏情况:取决于步长序列。

  1. 计数排序(Counting Sort):适用于一定范围内的整数排序,通过统计每个元素出现的次数,然后计算每个元素的位置,重复执行直到排序完成。
function countingSort(arr) {
  const n = arr.length;
  let max = Math.max(...arr);
  let min = Math.min(...arr);
  const range = max - min + 1;
  const count = Array(range).fill(0);
  const output = Array(n);

  for (let i = 0; i < n; i++) {
    count[arr[i] - min]++;
  }

  for (let i = 1; i < range; i++) {
    count[i] += count[i - 1];
  }

  for (let i = n - 1; i >= 0; i--) {
    output[count[arr[i] - min] - 1] = arr[i];
    count[arr[i] - min]--;
  }

  for (let i = 0; i < n; i++) {
    arr[i] = output[i];
  }

  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(countingSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:适用于小范围整数排序。
时间复杂度:O(n + k),其中 n 是输入数组元素个数,k 是输入范围大小。

  1. 桶排序(Bucket Sort):将元素根据一定规则放入不同的桶中,每个桶内部进行排序,然后按顺序合并桶内的元素,重复执行直到排序完成。
function bucketSort(arr, bucketSize = 5) {
  if (arr.length === 0) return arr;

  const max = Math.max(...arr);
  const min = Math.min(...arr);
  const bucketCount = Math.floor((max - min) / bucketSize) + 1;
  const buckets = Array(bucketCount).fill().map(() => []);

  for (let i = 0; i < arr.length; i++) {
    const 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]);
    arr.push(...buckets[i]);
  }

  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(bucketSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:适用于均匀分布的数据。
时间复杂度:O(n + k),其中 n 是输入数组元素个数,k 是桶的个数。

  1. 基数排序(Radix Sort):按照位数将元素分配到不同的桶中,然后按顺序合并桶内的元素,重复执行直到所有位数排序完成。
function radixSort(arr) {
  const max = Math.max(...arr);
  const maxLength = String(max).length;
  let bucket = Array.from({ length: 10 }, () => []);

  for (let i = 0; i < maxLength; i++) {
    for (let j = 0; j < arr.length; j++) {
      const digit = Math.floor(arr[j] / 10 ** i) % 10;
      bucket[digit].push(arr[j]);
    }
    arr.length = 0;
    for (let k = 0; k < bucket.length; k++) {
      arr.push(...bucket[k]);
      bucket[k].length = 0;
    }
  }

  return arr;
}

const arr = [64, 34, 25, 12, 22, 11, 90];
console.log(radixSort(arr)); // Output: [11, 12, 22, 25, 34, 64, 90]

特点:适用于数字位数相同的整数排序。
时间复杂度:O(d * (n + k)),其中 d 是最大数字的位数,n 是输入数组元素个数,k 是输入范围大小。

每种排序算法都有不同的时间复杂度和适用场景。在实际应用中,根据数据规模和性能要求选择合适的排序算法是很重要的。文章来源地址https://www.toymoban.com/news/detail-615897.html

到了这里,关于数据结构基础之排序算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构——排序算法——归并排序

    在第二个列表向第一个列表逐个插入的过程中,由于第二个列表已经有序,所以后续插入的元素一定不会在前面插入的元素之前。在逐个插入的过程中,每次插入时,只需要从上次插入的位置开始,继续向后寻找插入位置即可。这样一来,我们最多只需要将两个有序数组遍历

    2024年02月09日
    浏览(27)
  • 数据结构和算法笔记4:排序算法-归并排序

    归并排序算法完全遵循分治模式。直观上其操作如下: 分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列。 解决:使用归并排序递归地排序两个子序列。 合并:合并两个已排序的子序列以产生已排序的答案。 我们直接来看例子理解算法的过程,下面是要排序

    2024年01月21日
    浏览(47)
  • 【数据结构与算法】十大经典排序算法-希尔排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 希尔排序是一种插入排序的改进版本,旨在解决插入排序在处理大规模数据时的效率问题。通过将数组分为多个子序列并对

    2024年02月12日
    浏览(56)
  • 【数据结构与算法】十大经典排序算法-插入排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 插入排序(Insertion Sort)是一种简单直观的排序算法,其基本思想是将一个记录插入到已排好序的有序序列中,直到所有记录

    2024年02月13日
    浏览(60)
  • 【数据结构与算法】十大经典排序算法-快速排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌞 知乎 :HelloCode 🌴 掘金 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 快速排序(Quick Sort)是一种高效的排序算法,是对冒泡排序的优化。它采用分治法(Divide and Conquer)的思想,将待排序序列

    2024年02月13日
    浏览(47)
  • 【数据结构与算法】十大经典排序算法-冒泡排序

    🌟 个人博客: www.hellocode.top 🏰 Java知识导航: Java-Navigate 🔥 CSDN: HelloCode. 🌴 掘金 :HelloCode 🌞 知乎 :HelloCode ⚡如有问题,欢迎指正,一起学习~~ 冒泡排序(Bubble Sort)是一种简单的排序算法,它通过重复地交换相邻元素的位置来将最大(或最小)的元素逐步“冒泡”到

    2024年02月14日
    浏览(53)
  • 数据结构——排序算法之快速排序

        个人主页: 日刷百题 系列专栏 : 〖C/C++小游戏〗 〖Linux〗 〖数据结构〗   〖C语言〗 🌎 欢迎各位 → 点赞 👍+ 收藏 ⭐️+ 留言 📝  ​ ​ 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。 基本思想: 任取待排序元素序列中 的某元素作为基准值,按照

    2024年01月21日
    浏览(39)
  • 【数据结构与算法】排序算法(选择排序,冒泡排序,插入排序,希尔排序)

    基本概念这了就不浪费时间解释了,这四种都是很简单的排序方式,本专栏后续文章会出归并排序,计数排序,快速排序,堆排序,桶排序等排序算法,今天这篇文章中给出选择排序,冒泡排序,插入排序和希尔排序的实现; 如果发现文章中有错误,还请大家指出来,我会非

    2024年02月15日
    浏览(50)
  • 数据结构与算法-排序算法

    递归将整个函数的调用过程 调用过程 如何在CSDN博客中插入公式和各种符号 类似二叉树的后续遍历 递归行为和递归行为时间复杂度的估算 master 公式 : T ( n ) = a × T ( n b ) + O ( n d ) T(n) = a times T (frac{n}{b}) + O(n^d) T ( n ) = a × T ( b n ​ ) + O ( n d ) T ( n ) T(n) T ( n ) : 母问题的规模

    2024年02月15日
    浏览(37)
  • 算法 数据结构 递归插入排序 java插入排序 递归求解插入排序算法 如何用递归写插入排序 插入排序动图 插入排序优化 数据结构(十)

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

    2024年02月09日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包