js常用的6中排序算法

112 阅读3分钟

   情景:一个js数组中,数组中包含大量的对象,对象中有个qwe属性,且属性值为阿拉伯数组,根据对这个属性值对数组里的对象进行排序

  1.使用快速排序(这个场景下,使用快速排序是最优的)

function compare(a, b) {
  const qweA = a.qwe;
  const qweB = b.qwe;

  if (qweA < qweB) {
    return -1;
  }
  if (qweA > qweB) {
    return 1;
  }
  return 0;
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
arr.sort(compare);
console.log(arr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  优点:

  1. 平均时间复杂度为O(nlogn),性能较好。
  2. 它是一种原地排序算法,不需要额外的存储空间。
  3. 它的实现比较简单,代码量较小。

  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].qwe > arr[j + 1].qwe) {
        const temp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = temp;
      }
    }
  }

  return arr;
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
const sortedArr = bubbleSort(arr);
console.log(sortedArr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  需要注意的是,由于冒泡排序的时间复杂度为 O(n^2),因此不适用于处理大量数据。如果需要排序的数组过大,建议使用其他排序算法。

3.递归排序也称为归并排序

function mergeSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }

  const mid = Math.floor(arr.length / 2);
  const leftArr = arr.slice(0, mid);
  const rightArr = arr.slice(mid);

  return merge(mergeSort(leftArr), mergeSort(rightArr));
}

function merge(leftArr, rightArr) {
  const result = [];

  while (leftArr.length && rightArr.length) {
    if (leftArr[0].qwe <= rightArr[0].qwe) {
      result.push(leftArr.shift());
    } else {
      result.push(rightArr.shift());
    }
  }

  return result.concat(leftArr, rightArr);
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
const sortedArr = mergeSort(arr);
console.log(sortedArr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  需要注意的是,由于递归排序的时间复杂度为 O(nlogn),它的性能较好。但是,由于它是递归实现,所以会占用较多的系统栈空间,当需要排序的数组较大时,可能会导致堆栈溢出。

4.选择排序

function selectionSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    let minIndex = i;
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j].qwe < arr[minIndex].qwe) {
        minIndex = j;
      }
    }
    if (minIndex !== i) {
      [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
    }
  }
  return arr;
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
const sortedArr = selectionSort(arr);
console.log(sortedArr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  需要注意的是,选择排序的时间复杂度为 O(n^2),性能较差,不适用于大规模数据的排序。

  5.插入排序

function insertionSort(arr) {
  for (let i = 1; i < arr.length; i++) {
    let j = i;
    while (j > 0 && arr[j].qwe < arr[j - 1].qwe) {
      [arr[j], arr[j - 1]] = [arr[j - 1], arr[j]];
      j--;
    }
  }
  return arr;
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
const sortedArr = insertionSort(arr);
console.log(sortedArr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  需要注意的是,插入排序的时间复杂度为 O(n^2),性能较差,不适用于大规模数据的排序

  6.堆排序

function heapSort(arr) {
  buildMaxHeap(arr);
  for (let i = arr.length - 1; i >= 1; i--) {
    swap(arr, 0, i);
    maxHeapify(arr, 0, i);
  }
  return arr;
}

function buildMaxHeap(arr) {
  const n = arr.length;
  for (let i = Math.floor(n / 2); i >= 0; i--) {
    maxHeapify(arr, i, n);
  }
}

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

function swap(arr, i, j) {
  [arr[i], arr[j]] = [arr[j], arr[i]];
}

const arr = [{qwe: 4}, {qwe: 2}, {qwe: 6}, {qwe: 1}, {qwe: 5}];
const sortedArr = heapSort(arr);
console.log(sortedArr); // [{qwe: 1}, {qwe: 2}, {qwe: 4}, {qwe: 5}, {qwe: 6}]

  优缺点总结:

  1. 冒泡排序(Bubble Sort) 优点:简单易懂,代码实现容易。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
  2. 选择排序(Selection Sort) 优点:简单易懂,空间复杂度低。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
  3. 插入排序(Insertion Sort) 优点:简单易懂,对小规模数据的排序效率较高。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
  4. 快速排序(Quick Sort) 优点:效率较高,适合处理大规模数据。 缺点:快速排序的实现比较复杂,需要考虑大量细节,且对于一些特殊情况下的数据,效率较低。
  5. 归并排序(Merge Sort) 优点:稳定且效率高,适合处理大规模数据。 缺点:需要额外的内存空间,空间复杂度较高。
  6. 堆排序(Heap Sort) 优点:效率高,适合处理大规模数据。 缺点:实现比较复杂,需要维护堆的性质,并且空间复杂度较高。

   需要根据实际情况选择不同的排序算法。对于小规模数据,选择简单的排序算法即可;对于大规模数据,可以选择效率较高的算法。同时也要考虑数据的特点,如是否有大量重复元素、是否基本有序等,以便选择适合的排序算法。