[アルゴリズムとデータ構造] JavaScript はトップ 10 の並べ替えアルゴリズムを実装します (1)

ソートアルゴリズムについて

ここに画像の説明を挿入します

安定した並べ替え:並べ替えプロセス中に同じキー値を持つ要素は、並べ替え後も相対的な元の順序を維持します。これは、現在 2 つの要素 a と b があり、a が b の前にランクされ、a==b であることを意味します。ソート後も、a は依然として b の前にあります。これは安定したソートです。

不安定なソート:ソート処理中に同じキー値を持つ要素が、ソート後に相対的な順序が変わる可能性があります。これは、2 つの要素 a と b があることを意味します。元のシーケンスでは、a は b の前にあります。並べ替えると、a が b の後に表示され、それらの相対位置が変わる可能性があります。

In-situ ソート:ソート プロセス中に追加のストレージ スペースを申請する必要はなく、ソート対象のデータを元々保存していたストレージ スペースのみがデータ ソートの比較と交換に使用されます。これは、インプレース並べ替えでは、並べ替え結果を保存するための新しいデータ構造を作成せずに、並べ替え操作によって元のデータが直接変更されることを意味します。

非インプレース並べ替え:並べ替えプロセス中に、元のデータを直接変更せずに一時データまたは並べ替え結果を保存するための追加のストレージ スペースを申請する必要があります。

バブルソート

基本的な考え方:隣接する要素間の比較と交換を通じて、ソート コードの小さい要素が下から上に徐々に移動します。選別作業全体が水中の泡のように徐々に盛り上がっていくことから、バブルソーティングと呼ばれています。

手順:

  • 2 つの隣接する要素を比較します。最初の要素が 2 番目の要素より大きい場合は、2 つの要素を交換します。
  • 配列の終わりまで上記の手順を繰り返します。
  • 並べ替えが完了するまで、上記の 2 つの手順を繰り返します。
    ここに画像の説明を挿入します

例:

小さいものからa=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]大きいものまで並べます。

  <script>
    function BubbleSort(arr) {
    
    
      for (let i in arr) {
    
    
        // 每次循环都能找到一个最大的数放在最右边
        for (let j = 0; j < arr.length - 1 - i; j++) {
    
    
          if (arr[j] > arr[j + 1]) {
    
    
            let temp = arr[j]
            arr[j] = arr[j + 1]
            arr[j + 1] = temp
          }
        }
      }
      console.log(arr);
      return arr
    }
    let a = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    BubbleSort(a)
  </script>

要約:安定したソートには非常に小さなスペースが必要で、スペースの複雑さは O(1)、時間の複雑さは O(n²) です。

選択ソート

基本的な考え方:まず、ソートされていないシーケンス内で最小 (大きい) 要素を見つけてソートの開始位置に格納します。次に、ソートされていない残りの要素から最小 (大きい) 要素を見つけてソートの開始位置に配置します。ソートされたシーケンス。すべての要素がソートされるまで続きます。

手順:

  • 配列範囲内の最小 (最大) 要素を見つけて、それを開始位置要素と交換します。
  • ソートされた要素に加えて、残りの配列範囲で最小 (最大) の要素を見つけ、それを残りの配列の開始要素と交換します。
    ここに画像の説明を挿入します
    例:

小さいものからa=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]大きいものまで並べます。

  <script>
    function SelectionSort(arr) {
    
    
      for (let i in arr) {
    
    
        // 声明一个变量,用来接收当前最小值的下标
        let min = i
        for (let j = i; j < arr.length; j++) {
    
    
          if (arr[j] < arr[min]) {
    
    
            min = j
          }
        }
        let temp = arr[i]
        arr[i] = arr[min]
        arr[min] = temp
      }
      console.log(arr);
      return arr
    }
    let a = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    SelectionSort(a)
  </script>

分析:不安定なソートではスペースがほとんど必要なく、スペースの計算量は O(1)、時間の計算量は O(n²) です。

挿入ソート

基本的な考え方:配列を 2 つの部分に分割し、1 つの部分はソートされ、もう 1 つの部分はソートされていません。最初は、ソートされた部分には配列の最初の要素のみが含まれ、その後、ソートされていない部分の要素がソートされた部分に順番に挿入されるため、ソートされた部分は順序どおりに残ります。

手順:

  • 最初の数値を基準にして、二番目の数値を取り出して比較し、それより大きい場合は右側に、小さい場合は左側に、小さい場合は左側に置きます。
  • 3番目の数字を取り出して、前の数字と比較し、それが大きければ右側に置き、小さければ前の数字と比較して、より小さい数字を見つけます。
  • 上記の手順を繰り返してください
    ここに画像の説明を挿入します
    。例:

小さいものからa=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]大きいものまで並べます。

  <script>
    function InsertionSort(arr) {
    
    
      // 以第一个数作为基准
      for (let i = 1; i < arr.length; i++) {
    
    
        let temp = arr[i]
        let j;
        // 如果遍历的元素大于取出的元素,则遍历过的元素都需要后移一位
        for (j = i - 1; j >= 0 && a[j] > temp; j--) {
    
    
          arr[j + 1] = arr[j]
        }
        arr[j + 1] = temp
      }
      console.log(arr);
    }
    let a = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    InsertionSort(a)
  </script>

分析:安定した並べ替えに必要なスペースは非常に少なく、スペースの計算量は O(1)、時間の計算量は O(n²) です。

ヒルソート

基本的な考え方:これは挿入ソートの改良版で、元の配列を複数のサブシーケンスに分割し、挿入ソートを使用してサブシーケンスをソートし、最後にそれらを順序付けられたシーケンスにマージします。

手順:

  • インクリメント シーケンス (間隔シーケンス) を選択します。通常は、最初は配列長の半分の増分で、その後徐々に増分が減少します。
  • 元の配列を複数のサブシーケンスに段階的に分割します。各サブシーケンスは小さな配列として見ることができます。
  • 挿入ソート アルゴリズムを各サブシーケンスに適用して、サブシーケンス内の要素をソートします。
  • 増分を徐々に減らし、増分が 1 になるまで上記の手順を繰り返します。
  • 最後の増分が 1 の場合、配列全体がシーケンスとして扱われ、挿入ソートが再度適用されます。

ここに画像の説明を挿入します

例:

小さいものからa=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]大きいものまで並べます。

  <script>
    function ShellSort(arr) {
    
    
      // 选择初始的增量(gap)为数组长度的一半Math.floor(arr.length / 2)
      for (let gap = Math.floor(arr.length / 2); gap > 0; gap = Math.floor(gap / 2)) {
    
    
        // 对每个子序列进行插入排序
        for (let i = gap; i < arr.length; i++) {
    
    
          const temp = arr[i]
          let j;
          for (j = i - gap; j >= 0 && arr[j] > temp; j -= gap) {
    
    
            arr[j + gap] = arr[j]
          }
          arr[j + gap] = temp
        }
      }
      console.log(arr);
    }
    let a = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    ShellSort(a)
  </script>

分析:不安定なソートでは、スペースがほとんど必要ありません。スペースの複雑さは O(1)、時間の複雑さは O(nlog(n)) です。

マージソート

基本的な考え方:これは、分割統治戦略に基づいたソート アルゴリズムであり、ソート対象の配列をいくつかのサブシーケンスに分割し、個別にソートしてから、これらのサブシーケンスをマージして全体的な順序付けを実現します。マージ ソートの主な手順には、分割、並べ替え、マージの 3 つの段階が含まれます。

手順:

  • 分割: ソートする配列を 2 つのほぼ等しいサブ配列に分割し、2 つのサブ配列を再帰的にソートします。
  • 並べ替え: 部分配列の長さが 1 (要素が 1 つだけ) になるまで、各部分配列を再帰的に並べ替えます。この時点で、順序付けされていると見なされます。
  • マージ: ソートされたサブ配列を新しい順序配列にマージします。このステップの重要な点は、2 つの順序付きサブ配列を、より大きな順序付き配列にマージすることです。
    ここに画像の説明を挿入します
    例:

小さいものからa=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]大きいものまで並べます。

  <script>
    function MergeSort(arr) {
    
    
      if (arr.length <= 1) return arr;

      // 分割数组
      const middle = Math.floor(arr.length / 2)
      const left = arr.slice(0, middle)
      const right = arr.slice(middle)
      // 递归分割+排序
      const leftSort = MergeSort(left)
      const rightSort = MergeSort(right)

      return SequencSort(leftSort, rightSort)
    }
    function SequencSort(left, right) {
    
    
      let 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))
    }
    let a = [3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48]
    MergeSort(a)
  </script>

分析:安定したソート、空間計算量は O(n)、時間計算量は O(nlog(n)) です。

おすすめ

転載: blog.csdn.net/aDiaoYa_/article/details/133122263
おすすめ