数据结构中的各种排序方法小结(JS实现)

yizhihongxing

数据结构中的各种排序方法小结(JS实现)

本文将介绍常见的八种排序算法:

  1. 冒泡排序
  2. 插入排序
  3. 选择排序
  4. 快速排序
  5. 归并排序
  6. 堆排序
  7. 希尔排序
  8. 计数排序

下面进行详细讲解。

冒泡排序

冒泡排序是一种简单的排序算法,它重复地遍历数组,比较相邻的两个元素,并按大小交换位置,一直到整个数组排序完成。它的时间复杂度为O(n^2)。

示例代码:

function bubbleSort(arr) {
  const len = arr.length;
  for (let i = 0; i < len; 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;
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = bubbleSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

插入排序

插入排序是一种简单的排序算法,它每次从未排序的数组中取出第一个元素,将它插入到已排序的数组中的合适位置。插入操作需要将插入位置后面的元素逐个后移,直到找到合适的位置。它的时间复杂度为O(n^2)。

示例代码:

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

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = insertionSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

选择排序

选择排序是一种简单的排序算法,它每次从未排序的数组中选出最小(大)的元素,放到已排序的数组的末尾。它的时间复杂度为O(n^2)。

示例代码:

function selectionSort(arr) {
  const len = arr.length;
  for (let i = 0; i < len; 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;
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = selectionSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

快速排序

快速排序是一种常用的排序算法,它采用分治法的思想,将数组分成左右两个子数组,确定一个基准元素,将小于基准元素的放在左边,大于基准元素的放在右边,然后对左右两个子数组递归地调用快速排序。它的时间复杂度为O(nlogn)。

示例代码:

function quickSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  const pivotIndex = Math.floor(arr.length / 2);
  const pivot = arr.splice(pivotIndex, 1)[0];
  const left = [];
  const right = [];
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
  return quickSort(left).concat([pivot], quickSort(right));
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = quickSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

归并排序

归并排序是一种稳定的排序算法,它使用分治法的思想,将数组递归地分成两半,对每一半递归地调用归并排序,最后将两个有序的子数组归并成一个有序的数组。它的时间复杂度为O(nlogn)。

示例代码:

function mergeSort(arr) {
  if (arr.length <= 1) {
    return arr;
  }
  const mid = Math.floor(arr.length / 2);
  const left = arr.slice(0, mid);
  const right = arr.slice(mid);
  return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right) {
  const result = [];
  let leftIndex = 0;
  let rightIndex = 0;
  while (leftIndex < left.length && rightIndex < right.length) {
    if (left[leftIndex] < right[rightIndex]) {
      result.push(left[leftIndex]);
      leftIndex++;
    } else {
      result.push(right[rightIndex]);
      rightIndex++;
    }
  }
  return result.concat(left.slice(leftIndex), right.slice(rightIndex));
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = mergeSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

堆排序

堆排序是一种树形选择排序算法,它的本质是利用堆这种数据结构来维护数组的顺序,利用堆这种数据结构来实现了一个优先队列,堆顶元素为整个堆中的最大(或最小)值。它的时间复杂度为O(nlogn)。

示例代码:

function heapSort(arr) {
  // 对数组进行堆化
  for (let i = Math.floor(arr.length / 2) - 1; i >= 0; i--) {
    heapify(arr, i, arr.length);
  }
  // 依次从堆中取出最大值,放到数组末尾
  for (let i = arr.length - 1; i > 0; i--) {
    [arr[0], arr[i]] = [arr[i], arr[0]];
    heapify(arr, 0, i);
  }
  return arr;
}

function heapify(arr, i, len) {
  let largest = i;
  const left = 2 * i + 1;
  const 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, largest, len);
  }
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = heapSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

希尔排序

希尔排序是一种插入排序的变体。它的基本思想是:将数组分成若干个子序列,对每个子序列进行插入排序,每次减少子序列的长度,最后整个数组变成一个有序序列。希尔排序的时间复杂度与选取的增量序列有关,不同的增量序列有不同的时间复杂度。最坏情况下的时间复杂度为O(n^2)。

示例代码:

function shellSort(arr) {
  const len = arr.length;
  let gap = Math.floor(len / 2);
  while (gap > 0) {
    for (let i = gap; i < len; i++) {
      const 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;
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = shellSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

计数排序

计数排序是一种非基于比较的排序算法,它的核心思想是:统计每个元素出现的次数,计算出每个元素应该出现的位置。它的时间复杂度为O(n+k),其中k为计数数组的大小。

示例代码:

function countingSort(arr) {
  const max = Math.max(...arr);
  const min = Math.min(...arr);
  const len = max - min + 1;
  const count = new Array(len).fill(0);
  for (let i = 0; i < arr.length; i++) {
    count[arr[i] - min]++;
  }
  let index = 0;
  for (let i = 0; i < len; i++) {
    while (count[i] > 0) {
      arr[index++] = i + min;
      count[i]--;
    }
  }
  return arr;
}

const arr = [5, 2, 7, 1, 3, 6];
const sortedArr = countingSort(arr);
console.log(sortedArr); // [1, 2, 3, 5, 6, 7]

以上就是八种常见的排序算法的介绍和JS代码实现。对于每种算法的时间复杂度和优缺点,可以根据实际情况选择使用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:数据结构中的各种排序方法小结(JS实现) - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • 数据结构之哈夫曼树与哈夫曼编码

    一、背景 编码是信息处理的基础(重新表示信息)。 普通的编码是等长编码,例如7位的ASCIL编码,对出现频率不同的字符都使用相同的编码长度。但其在传输和存储等情况下编码效率不高。 可使用不等长编码,来压缩编码:高频字符编码长度更短,低频字符编码长度更长。   [例] 将百分制的考试成绩转换成五分制的成绩 按顺序分别编码。 按频率分别编码(高频短编码,类似于香…

    算法与数据结构 2023年4月17日
    00
  • 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解

    解析从源码分析常见的基于Array的数据结构动态扩容机制的详解 什么是动态扩容机制 动态扩容机制是指,当一个数据结构达到其容量限制时,自动增加容量大小以继续存储新的数据。在动态扩容时,需要考虑到时间和空间的平衡,因为扩容需要分配新的内存空间,在处理大量数据时,需要尽可能减少空间浪费和分配内存的时间消耗。 基于Array的数据结构 Array是一种连续存储的数…

    数据结构 2023年5月17日
    00
  • C++高级数据结构之并查集

    C++高级数据结构之并查集 什么是并查集 并查集(Union Find Set)是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。 并查集定义了如下的三种操作: 1、makeSet(s):建立一个新的并查集,其中包含s个单元素集合。 2、unionSet(x, y):把元素x和元素y所在的集…

    数据结构 2023年5月17日
    00
  • C#数据结构之队列(Quene)实例详解

    C#数据结构之队列(Quene)实例详解 什么是队列? 队列是一种线性数据结构,只允许在队列的两端进行操作。队列是一种FIFO(First in First Out)的数据结构,即先进先出,类似于排队买票的场景。 C#中的队列(Quene) C#中队列(Quene)是System.Collections命名空间中的一个类,可以通过引入System.Colle…

    数据结构 2023年5月17日
    00
  • Redis之常用数据结构哈希表

    Redis之常用数据结构哈希表 Redis是一种开源的、高性能的、基于内存的数据存储系统,它支持多种数据结构,包括字符串、哈希表、列表、集合和有序集合等。其中哈希表是一种常用的数据结构,本文将详细讲解Redis中的哈希表。 哈希表概述 哈希表是一种通过哈希函数和数组实现的数据结构,能够快速地进行插入、查找和删除等操作,时间复杂度为O(1)。在Redis中,哈…

    数据结构 2023年5月17日
    00
  • Java数据结构之稀疏数组的实现与应用

    Java数据结构之稀疏数组的实现与应用 什么是稀疏数组 稀疏数组是一种刻画二维数组中许多元素值都为0的特殊数据结构。它可以提高存储空间的利用率,实现对数据的压缩和优化,减少不必要的处理,提升程序的运行效率。 在稀疏数组中,只有非零元素被存储,而这些元素的索引信息和具体数值的信息都会被记录下来。 稀疏数组的实现与应用 实现步骤 创建原始的二维数组,存入多个元素…

    数据结构 2023年5月17日
    00
  • C语言数据结构实现银行模拟

    C语言数据结构实现银行模拟攻略 背景介绍 银行模拟是计算机学科中一个重要的数据结构实践练习项目。它涉及到队列(Queue)等数据结构的应用,也是计算机基础课程的一个重要组成部分。 代码实现 1. 队列的实现 首先,我们需要实现一个队列(Queue)结构体,包含 QueueSize、Front、Rear 三个成员变量: struct Queue { int Q…

    数据结构 2023年5月17日
    00
  • 浅析Java 数据结构常用接口与类

    浅析 Java 数据结构常用接口与类 本文主要介绍 Java 中常用的数据结构接口和类,可以帮助读者了解和掌握常见的数据结构以及它们的实现方式,从而在日后的开发中使用它们,提高代码的效率和质量。 List 接口 List 接口是 Java 中常用的数据结构接口之一,它代表了一个有序的集合,集合中的每一个元素都可以通过其索引进行访问。List 接口的一些常用方…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部