2009-06-02 5 views

답변

48

사진 배열 ... are there four partition versions of quicksort, 요청 다른쪽에는 4보다 적은 모든 요소가 있습니다. 그래서 같이 :

3, 2, 0, 2, 4, | 8, 7, 8, 9, 6, 5 

세 파티션은 빠른 정렬는에 분할 두 개의 값을 선택하고 그 길 배열을 분할한다. 4 및 7을 선택할 수 있습니다.

3, 2, 0, 2, | 4, 6, 5, 7, | 8, 8, 9 

일반 퀵 정렬에는 약간의 변형이 있습니다.

배열을 정렬 할 때까지 각 분할 영역을 계속 분할합니다. 런타임은 기술적으로 nlog (n)이며 일반 quicksort의 nlog (n)과 약간 다릅니다.

+2

+1. – cgp

+0

감사합니다. – jjnguy

+10

흥미로운 질문은 "어떤 조건에서 m-way QS보다 n-way QS가 더 나은가?"입니다. – dmckee

14

http://www.sorting-algorithms.com/static/QuicksortIsOptimal.pdf

은 참조 :

http://www.sorting-algorithms.com/quick-sort-3-way

나는 면접 질문 버전은 흥미로운 생각했다.

3, 5, 2, 7, 6, 4, 2, 8, 8, 9, 0 

두 개의 파티션이 빠른 정렬 4 말, 값을 선택하고 배열의 한면에 4보다 큰 모든 요소를 ​​넣어 것입니다 : 그것은

+2

이것은 올바른 대답 인 것 같습니다. 3 중 빠른 정렬은 많은 중복 키가있는 경우 성능을 처리합니다. 간결한 설명을 위해 –

12

Akra-Bazzi formula을 사용하여 파티션 수를 매개 변수로두고 그 매개 변수를 최적화하면 e (= 2.718 ...) 파티션이 가장 빠른 성능을 제공합니다. 실제로, 우리의 언어 구조, CPU 등은 모두 바이너리 연산에 최적화되어 있으므로 표준 파티션을 두 세트로 분할하는 것이 가장 빠릅니다.

+0

아! 내가 뭘 찾고 있었는지. 감사. – dmckee

+2

'두 세트의 표준 파티셔닝이 가장 빠름'- ** 표창장 필요 ** – Johan

10

3 방향 파티션은 Djstrka가 사용합니다.

같음,

기본적으로는 이하 3 개 분할을 설정 {17, 3, 9, 4, 1, 2, 3, 15, 17, 25}을 요소로하는 배열 생각해 더 큰 보다. 파티션 피벗, 피벗보다 작은 모든 요소 및 피벗보다 큰 모든 요소. 피벗과 동일한 모든 요소를 ​​제자리에서 이동합니다.

+1

이것이 올바른 대답이라고 생각합니다. –

-1
//code to implement Dijkstra 3-way partitioning 

    package Sorting; 

    public class QuickSortUsing3WayPartitioning { 

private int[]original; 
private int length; 
private int lt; 
private int gt; 

public QuickSortUsing3WayPartitioning(int len){ 
    length = len; 
    //original = new int[length]; 

    original = {0,7,8,1,8,9,3,8,8,8,0,7,8,1,8,9,3,8,8,8}; 

} 

public void swap(int a, int b){ //here indexes are passed 
    int temp = original[a]; 
    original[a] = original[b]; 
    original[b] = temp; 
} 

public int random(int start,int end){ 
    return (start + (int)(Math.random()*(end-start+1))); 
} 

public void partition(int pivot, int start, int end){ 
    swap(pivot,start); // swapping pivot and starting element in that subarray 

    int pivot_value = original[start]; 
    lt = start; 
    gt = end; 

    int i = start; 
    while(i <= gt) { 

     if(original[i] < pivot_value) { 
      swap(lt, i); 
      lt++; 
      i++; 
     } 

     if(original[i] > pivot_value) { 
      swap(gt, i); 
      gt--; 
     } 
     if(original[i] == pivot_value) 
      i++; 
    } 
} 

public void Sort(int start, int end){ 
    if(start < end) { 

     int pivot = random(start,end); // choose the index for pivot randomly 
     partition(pivot, start, end); // about index the array is partitioned 

     Sort(start, lt-1); 
     Sort(gt+1, end); 

    } 
} 

public void Sort(){ 
    Sort(0,length-1); 
} 

public void disp(){ 
    for(int i=0; i<length;++i){ 
     System.out.print(original[i]+" "); 
    } 
    System.out.println(); 
} 

public static void main(String[] args) { 

    QuickSortUsing3WayPartitioning qs = new QuickSortUsing3WayPartitioning(20); 
    qs.disp(); 

    qs.Sort(); 
    qs.disp(); 

} 

} 
+0

{} 표기법을 사용하여 한 줄로 원본을 초기화하지 않는 이유는 무엇입니까? 바로 지금,보기 흉하게 보입니다. – CyprUS

+1

@CyprUS 완료, 제안 주셔서 감사합니다 –

+0

답변에서 _ 어떻게 대답합니까? '3 방향 파티션이있는 QuickSort 란 무엇입니까?' 이것은 또한 "네덜란드 국기 알고리즘"이라고도합니다 - "이중 피벗"은 어떻습니까? – greybeard

0

난이 파티션 elemnts의 피봇보다 작은 동일하고 큰 분할 익스트라 방법에 관한 것이다 생각한다. 더 작고 큰 파티션 만 재귀 적으로 정렬해야합니다. 대화식 시각화를보고 the walnut으로 게임을 할 수 있습니다. 파티셔닝 방법이 일반적으로 "네덜란드 깃발 문제"라고 불리기 때문에 내가 사용한 색상은 빨간색/흰색/파란색입니다.