[Javaデータ構造]クイックソートの実装

ここに画像の説明を挿入します
みなさん、ようこそ〜
一緒に学び、一緒に進歩しましょう〜

1. 高速ソートの原則:一般に3つのステップに分けられます:
1。参照値としてソートする間隔から数値を選択します(通常は左端の数値を選択します)
2。パーティション:ソートする範囲全体をトラバースします。参照値よりも小さい(等しいを含めることができる)参照値の左側に配置し、参照値よりも大きい値(等しいを含めることができる)を参照値の右側に配置します。
3.分割統治のアイデアを採用し、セル間の長さが<= 1になるまで、左右のセルを同じように扱い、比較を終了します。

ここに画像の説明を挿入します
配列[3,5,2,7,9,4,8​​]を例にとると、高速ソートのプロセスです。
ここに画像の説明を挿入します
次に、比較のプロセスはパーティションのプロセスです
。Javaこの部分を実現するには3つの方法があります速いソート
1つのホーア方法
方法.Digging 2
3

ホーア方法のアイデアをトラバーサル方法の前と後
ここに画像の説明を挿入します

掘削方法のアイデア:基本的なアイデアはホア法と同じですが、交換ではなく、直接割り当て(掘削ピット+充填ピット)

前後のトラバーサルのアイデア:2番目の番号からトラバースし、最初の番号よりも小さい(または大きい)番号を見つけてから、最初の番号と交換します。アイデアは比較的単純で、誰もが見ることで理解できますコードで。

3. パフォーマンス分析:
時間計算量:最高O(n log(n))最悪O(n ^ 2)平均複雑度:O(n log(n))
空間計算量:最高:O(n log(n))最悪: O(n)平均:O(n log(n))
安定性:不安定

第四に、 高速キューの最適化方法について:
一般的なインタビュアーは質問するときにこれらの側面を考慮します。
1. paititionセクションを掘り下げる(細部の最適化)
2。比較の数が比較的少ない場合、クイックソートは最速ではありません;(間隔内の数が特定のしきい値(16)よりも小さい場合は、補間行)
3。特別な数値を選択する方法を最適化します-----比較値として左端の数値を
選択しますa。ランダムに選択しますb。いくつかの数値を選択し、中央のサイズ値を選択します(3番目の数値は選択)
4。等しい値を特に扱います

5つ目は、クイックソートのコード実装部分:( 3つの方法)は、小さいものから大きいものへのソートを実現することです。

public class Hoare {
    
    
    public static void quickSort(long[] array) {
    
    
        quickSortInternal(array, 0, array.length - 1);
    }

    // 区间是 [lowIndex, highIndex]
    private static void quickSortInternal(long[] array,int lowIndex,int highIndex) {
    
    
        // 由于是闭区间,所以,区间内个个数需要加个 1
        int size = highIndex - lowIndex + 1;
        if (size <= 1) {
    
    
            return;
        }

        // 选择其中一个数(选最左边的) —— array[lowIndex]
        // 执行 partition,小的放左,大的放右
        // keyIndex 是经过 partition 之后,选出来的数最终所在下标
        int keyIndex = partition(array, lowIndex, highIndex);
        // 分别对左右区间进行相同的处理 —— 递归方法
        quickSortInternal(array, lowIndex, keyIndex - 1);
        quickSortInternal(array, keyIndex + 1, highIndex);
    }

    // 区间是 array[lowIndex, highIndex]
    // 1. 选择 array[lowIndex] 作为特殊的数
    // 2. 需要遍历整个区间(不能遗漏任何的数)和 选出来的数比较
    // 3. 保证 小于等于的在左边,大于等于的在右边(但没有顺序要求)
    private static int partition(long[] array, int lowIndex, int highIndex) {
    
    
        // 选择合适的方法
        return partitionHover(array, lowIndex, highIndex);
    }

    private static void swap(long[] array, int index1, int index2) {
    
    
        long t = array[index1];
        array[index1] = array[index2];
        array[index2] = t;
    }

    private static int partitionHover(long[] array, int lowIndex, int highIndex) {
    
    
        int leftIndex = lowIndex;
        int rightIndex = highIndex;
        // 选择的数是最左边的一个
        long key = array[lowIndex];
        // 选择了最左边,从右边先走
        // 停止条件 leftIndex == rightIndex
        // 循环的继续的条件 leftIndex < rightIndex
        while (leftIndex < rightIndex) {
    
    

            while (leftIndex < rightIndex && array[rightIndex] >= key) {
    
    
                rightIndex--;
            }
            // 说明 [rightIndex] 遇到了小的了

            while (leftIndex < rightIndex && array[leftIndex] <= key) {
    
    
                leftIndex++;
            }
            // 说明 [leftIndex] 遇到了大的了

            swap(array, leftIndex, rightIndex);
        }

        swap(array, lowIndex, leftIndex);

        return leftIndex;
    }

    //挖坑
    private static int partitionHoare(long[] array,int lowIndex,int highIndex){
    
    
        int leftIndex=lowIndex;
        int rightIndex=highIndex;
        long key=array[lowIndex];
        while(leftIndex<rightIndex){
    
    

            while(leftIndex<rightIndex&&array[highIndex]>=key){
    
    
                rightIndex--;

            }
            //右边的值
            array[leftIndex]=array[rightIndex];

            while(leftIndex<rightIndex&&array[leftIndex]<key){
    
    
                leftIndex++;
            }
            array[rightIndex]=array[leftIndex];
        }
        array[leftIndex]=key;
        return leftIndex;
    }
//前后遍历的方法
    private static int partition前后(long[] array,int lowIndex,int highIndex){
    
    
        int separateIndex=lowIndex+1;
        for(int i=lowIndex+1;i<=highIndex;i++){
    
    
            if(array[i]<array[lowIndex]){
    
    
                swap(array,i,separateIndex);
                separateIndex++;
            }
        }
        swap(array,lowIndex,separateIndex-1);
        return separateIndex-1;
    }

おすすめ

転載: blog.csdn.net/m0_46551861/article/details/109192442