인터뷰 사이트 : 빠른 정렬 알고리즘 파쇄

알고리즘 개요

빠른 일종 이라고도 (퀵), 분할 교환 종류 , 언급 빠른 행을 처음 토니 호어에 의해 제안 된 정렬 알고리즘을. 평균 조건에서 비교 (N 로그 n) O n으로 항목을 정렬합니다. 최악의 상황에서 당신은 O (N ^ 2) 비교에 필요하지만,이 상황은 드문 일이 아니다.

그 내부 루프는 대부분의 아키텍쳐에 도달 효과적 일 수 있기 때문에 사실, 빠른 정렬 O, 일반적으로 속도가 매우 빠르고 다른 알고리즘에 비해 (N 로그 n).

알고리즘 과정

요약하여 정렬하여 분할 정복하고 크고 작은 두개의 서브 시퀀스의 순서에 넣어 전략하고 정렬 재귀 두 시퀀스.

단계 :

  1. 선택 기준 값은 : "기준"(피벗)라는 일련의 요소를 픽업
  2. 분할 : 재정렬 열 기준치보다 모두 작은 레퍼런스 뒤에 배치 기준값 요소보다 큰 전체 (기준값과 동일 측면의 임의의 수가 될 수 있음), 기준 소자의 전면에 배치된다. 이 분할 종료 후, 기준치의 정렬이 완료되었습니다
  3. 재귀 정렬 서열 재귀 레퍼런스 시퀀스 요소보다 작은 값이 요소의 정렬 순서의 기준 값보다 큰 것이다.

최하부 재귀 판정 조건은 열 수가 명백하게 지시되는 시점에서의 열 수 또는 제로의 크기이다.

구체적인 방법의 여러 가지 선택 기준 값이 선택 방법은 주문 시간의 성능에 결정적인 영향을 미친다.

빠른 정렬 코드 로직은 다음과 같이 표현 될 수있다 :

public void quick(int arr, int head, int tail) {
    /*
    * 1.递归终止条件
    * 2.定义头尾指针与基准值
    * 2.把小于基准数的移到左边,把大于基准数的移到右边
    */
    quick(arr, head, right); //继续处理左边的
    quick(arr, left, tail); //继续处理右边的
}

샘플 코드

public class QuickSort {
  
    public static void qSort(int[] arr, int head, int tail) {
        if (head >= tail || arr == null || arr.length <= 1) {
            return;
        }
        //定义俩指针 用于移动
        int left = head;
        int right = tail;
        int pivot = arr[head]; //基准值,也可以arr[(head + tail) / 2]

        while (left <= right) {
            while (arr[left] < pivot) { //左指针先走,找到大于等于基准数的停止
                ++left;
            }
            while (arr[right] > pivot) { //右指针后走,找到小于等于基准数的停止
                --right;
            }
            if (left < right) {
                //交换arr[left]和arr[right]的位置
                int t = arr[left];
                arr[left] = arr[right];
                arr[right] = t;
                //继续遍历
                ++left;
                --right;
            } else if (left == right) {
                //遍历完,错开两指针
                ++left;
                //break;
            }
        }

        qSort(arr, head, right);
        qSort(arr, left, tail);
    }

    public static void main(String[] args) {
        int[] arr = new int[]{6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
        qSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }
  
}

인쇄물 :

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

인쇄 매수 주문 및 분류하기 전에 프로그램 작업에서 프로세스가 관찰 한 칼럼을 통해 실행할 수 있습니다

对数组 [6 1 2 7 9 3 4 5 10 8 ] 排序, 排序后 [5 1 2 4 3 9 7 (6) 10 8 ] 
对数组 [5 1 2 4 3 ] 排序, 排序后 [3 1 2 4 (5) 9 7 6 10 8 ] 
对数组 [3 1 2 4 ] 排序, 排序后 [2 1 (3) 4 5 9 7 6 10 8 ] 
对数组 [2 1 ] 排序, 排序后 [1 (2) 3 4 5 9 7 6 10 8 ] 
对数组 [3 4 ] 排序, 排序后 [1 2 (3) 4 5 9 7 6 10 8 ] 
对数组 [9 7 6 10 8 ] 排序, 排序后 [1 2 3 4 5 8 7 6 10 (9) ] 
对数组 [8 7 6 ] 排序, 排序后 [1 2 3 4 5 6 7 (8) 10 9 ] 
对数组 [6 7 ] 排序, 排序后 [1 2 3 4 5 (6) 7 8 10 9 ] 
对数组 [10 9 ] 排序, 排序后 [1 2 3 4 5 6 7 8 9 (10) ] 

복잡도 분석

시간 복잡도

어레이는 n 개의 의한 재귀 계산에 요소는,이 시간이면 제 1 층 번째 경우, N / 2, N / 2 이해 재귀 호출 절반과 좌측 절반 부, 즉, 지지점 피봇의 위치를 산출 층은 N / 4, N / 4이며, N / 4, N / 4 알 네 부분, 즉 N 원소 그 층의 총 2 ^ N =에서 K = K (N)은 log2을 다음 각각 N의 복잡성, 그 평균은 O (nlog2 않음) 시간 복잡도. 당신은 표준 케이스의 종류의 경우 이미 오름차순으로, 다음 재귀의 오른쪽 절반이있는 경우 그러나 이것은 절반 제거 된 왼쪽, 확실히 평균 경우입니다. (제 n - 1) (제 n - 2) ... (1 개) *은, 이것의 복잡성 확실히 O (N- 형 ^ 2) .

우주의 복잡성

고속 방전이 재귀 호출 각 함수 호출을 달성에만 일정한 공간과 재귀 수준의 공간적 복잡도에 따라서 동일한 사용된다.

가장 좋은 상황은 O (LOG2의 n은) 대부분의 시간에 재귀 호출을 중첩 필요가 필요 O (LOG2의 n)의 공간. 그것은 필요로하는 중첩 된 재귀 호출의 최악의 경우 O (n)의 시간을 필요로 O (n)의 공간.

아는 거의 시간 복잡도를 참조

https://www.zhihu.com/question/22393997/answer/189896378

추천

출처www.cnblogs.com/yueshutong/p/11369126.html