情景:一个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}]
优点:
- 平均时间复杂度为O(nlogn),性能较好。
- 它是一种原地排序算法,不需要额外的存储空间。
- 它的实现比较简单,代码量较小。
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}]
优缺点总结:
- 冒泡排序(Bubble Sort) 优点:简单易懂,代码实现容易。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
- 选择排序(Selection Sort) 优点:简单易懂,空间复杂度低。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
- 插入排序(Insertion Sort) 优点:简单易懂,对小规模数据的排序效率较高。 缺点:时间复杂度较高,效率低,不适合处理大规模数据。
- 快速排序(Quick Sort) 优点:效率较高,适合处理大规模数据。 缺点:快速排序的实现比较复杂,需要考虑大量细节,且对于一些特殊情况下的数据,效率较低。
- 归并排序(Merge Sort) 优点:稳定且效率高,适合处理大规模数据。 缺点:需要额外的内存空间,空间复杂度较高。
- 堆排序(Heap Sort) 优点:效率高,适合处理大规模数据。 缺点:实现比较复杂,需要维护堆的性质,并且空间复杂度较高。
需要根据实际情况选择不同的排序算法。对于小规模数据,选择简单的排序算法即可;对于大规模数据,可以选择效率较高的算法。同时也要考虑数据的特点,如是否有大量重复元素、是否基本有序等,以便选择适合的排序算法。