[자바 데이터 구조] 빠른 정렬 구현

여기에 사진 설명 삽입
여러분 환영합니다 ~
함께 배우고 함께 발전합시다 ~

1. 빠른 정렬 원칙 : 일반적으로 세 단계로 나뉩니다.
1. 정렬 할 간격에서 기준 값으로 숫자를 선택합니다 (일반적으로 가장 왼쪽 숫자를 선택)
. 2. 파티션 : 정렬 할 전체 범위를 가로 지르면됩니다. 기준 값보다 작을 수 있음 (동일 포함 가능) 기준 값의 왼쪽에 놓고 기준 값보다 큰 값 (동일 포함 가능)을 기준 값의 오른쪽에 놓습니다.
3. 나누고 정복하는 아이디어를 채택하고 왼쪽과 오른쪽 세포를 같은 방식으로 처리하고 세포 사이의 길이가 <= 1이 될 때까지 비교를 종료합니다.

여기에 사진 설명 삽입
[3,5,2,7,9,4,8] 배열을 예로 들면 빠른 정렬 과정을들 수 있습니다.
여기에 사진 설명 삽입
둘째, 비교 과정은 Partition 과정입니다.
자바가
부분 을 구현하는
방법은 세 가지입니다 .빠른 정렬 :
1 개 호어 방법
이 .Digging 방법
3.

호어 방법의 아이디어를 전 탐색 방법 후 :
여기에 사진 설명 삽입

파기 방법의 아이디어 : 기본 아이디어는 Hoare 방법과 동일하지만 더 이상 교환하지 않고 직접 할당 (굴착 구덩이 + 채움 구덩이)

전후 순회 아이디어 : 두 번째 숫자에서 순회하고 첫 번째 숫자보다 작은 (또는 큰) 숫자를 찾은 다음 첫 번째 숫자와 교환합니다. 아이디어는 비교적 간단하며 모두가보고 이해할 수 있습니다. 코드에서.

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. 몇 개의 숫자를 선택하고 중간에있는 크기 값을 선택합니다 (세 번째 숫자는 선택)
4. 특히 동일한 값을 취급

다섯, 빠른 정렬의 코드 구현 부분 : (세 가지 방법) 작은 것에서 큰 것까지 정렬을 달성하는 것입니다.

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