0
0

デュアルピボットクイックソートの仕組みと実装

Posted at

デュアルピボットクイックソートとは

デュアルピボットクイックソートは、従来のクイックソートの一種で、2つのピボットを使用することでソートを効率化します。これにより、パーティションの分割がより細かくなり、アルゴリズムのパフォーマンスが向上します。

アルゴリズムの概要

  1. ピボットの選択:
    2つのピボットを選択します。通常、配列の先頭と末尾の要素が使用されます。

  2. パーティショニング:
    選択した2つのピボットを基準に、配列を3つの部分に分けます。

    • 左側の部分は、最初のピボットよりも小さい要素が含まれます。
    • 中央の部分は、2つのピボットの間の要素が含まれます。
    • 右側の部分は、2番目のピボットよりも大きい要素が含まれます。
  3. 再帰的ソート:
    分割された各部分に対して再帰的にデュアルピボットクイックソートを適用します。

アルゴリズムの利点

  • パフォーマンスの向上:
    デュアルピボットクイックソートは、2つのピボットを使用することでパーティショニングがより効率的になり、ソートのパフォーマンスが向上します。

  • 安定性:
    デュアルピボットクイックソートは不安定なソートですが、特定のケースでは安定性を保つことができます。

実装例

以下に、Javaでのデュアルピボットクイックソートの実装例を示します。

public class DualPivotQuickSort {

    public static void dualPivotQuickSort(int[] arr, int low, int high) {
        if (low < high) {
            // ピボットの選択とパーティショニング
            int[] pivots = partition(arr, low, high);
            int pivot1 = pivots[0];
            int pivot2 = pivots[1];

            // 左部分の再帰的ソート
            dualPivotQuickSort(arr, low, pivot1 - 1);
            // 中央部分の再帰的ソート
            dualPivotQuickSort(arr, pivot1 + 1, pivot2 - 1);
            // 右部分の再帰的ソート
            dualPivotQuickSort(arr, pivot2 + 1, high);
        }
    }

    private static int[] partition(int[] arr, int low, int high) {
        if (arr[low] > arr[high]) {
            swap(arr, low, high);
        }
        int pivot1 = arr[low];
        int pivot2 = arr[high];

        int lt = low + 1;
        int gt = high - 1;
        int i = low + 1;

        while (i <= gt) {
            if (arr[i] < pivot1) {
                swap(arr, i, lt);
                lt++;
            } else if (arr[i] > pivot2) {
                swap(arr, i, gt);
                gt--;
                i--; // swapで入れ替わった要素を再度チェックする
            }
            i++;
        }
        lt--;
        gt++;

        swap(arr, low, lt);
        swap(arr, high, gt);

        return new int[]{lt, gt};
    }

    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {24, 8, 42, 75, 29, 77, 38, 57};
        dualPivotQuickSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
}

コードの説明

  • dualPivotQuickSort メソッド:

    • 配列とその範囲(lowからhigh)を受け取り、ソートを行います。
    • partition メソッドを呼び出して、2つのピボットを基準に配列を3つの部分に分割します。
    • 各部分に対して再帰的にソートを行います。
  • partition メソッド:

    • 配列を2つのピボットを基準に3つの部分に分割します。
    • 2つのピボットを選択し、それらを基準に要素を入れ替えながらパーティショニングを行います。
    • 最終的に、ピボットの位置を返します。
  • swap メソッド:

    • 配列内の2つの要素を入れ替えます。

まとめ

デュアルピボットクイックソートは、従来のクイックソートを改良した効率的なソートアルゴリズムです。2つのピボットを使用することでパーティショニングを効率化し、パフォーマンスの向上を図ります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0