빠른 정렬을 위해 나쁜 경우를 만드는 것은 무엇입니까?


10

나는 quicksort에 대해 배우고 있으며 quicksort가 어려움을 겪을 다른 배열을 설명하고 싶습니다. 내가 생각한 퀵 정렬에는 초기 임의 셔플 링이 없으며 2 개의 파티션이 있으며 중앙값을 계산하지 않습니다.

나는 지금까지 세 가지 예를 생각해 보았다.

[1,2,3,4,5,6,7,8,9,10] - when the array is sorted
[10,9,8,7,6,5,4,3,2,1] - when the array is reversed
[1,1,1,1,1,1,1,1,1,1] - when the array is the same values
[1,1,1,2,2,2,3,3,3,3] - when there are few and unique keys

예를 들어, 나는 이것에 대해 너무 확실하지 않습니다.

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

그렇다면 퀵 정렬이 어려운 어레이와 비교하여 어려운 곳은 무엇입니까?


2
피벗은 어떻게 선택됩니까? 선택되지 않은 두 가지 방법을 선택했지만 선택 방법은 밝히지 않았습니다.
Winston Ewert

QuickSort에 최악의 경우를 알려주십시오. 언제 발생합니까? StackOverflow에서 읽기. 또한 sorting.at 는 정렬 알고리즘을 멋지게 시각화합니다.

@WinstonEwert 피벗은 첫 번째 요소에 의해 선택됩니다.
mrQWERTY

@ Renren29 나는 질문에게에 초점을 이동하려고 시도하는 약간 수정 한 이유 퀵이 지정된 배열에 어려움이 이유가 아니라 예를 배열을 추구하는 것보다 (나는 사람들이 당신의 답변을 제공 할하지 않는 [2,1,2,1,2,1,2,1]것을를 전체 인 대답). 이 질문의 목표는 이상적으로 다른 사람들이 와서 예제가 아닌 이유 (답이있는) 에 대해 더 많은 것을 알아낼 수있는 것 입니다.

퀵 정렬을 2 개의 요소 덩어리로 실행하고 있습니까? 실제 구현에서는 작은 청크에 대해 더 간단한 정렬을 사용하는 경향이 있기 때문입니다. 예를 들어 비교 및 ​​스왑은 N = 2의 퀵 정렬보다 훨씬 간단합니다.
MSalters

답변:


9

모든 정렬 알고리즘에는 최악의 경우가 있으며, 대부분의 경우 최악의 경우는 실제로 나빠서 테스트 할 가치가 있습니다. 문제는 기본 알고리즘을 알고 있기 때문에 최악의 경우는 없다는 것입니다.

일반적인 최악의 경우는 다음과 같습니다. 이미 정렬 됨; 반대로 정렬; 거의 정렬되지 않은 요소 하나; 모든 값이 동일합니다. 첫 번째 (또는 마지막)를 제외하고 모두 동일합니다. 우리는 최악의 경우가 특정한 톱니 패턴 인 경우가 있었는데, 이는 예측하기 어렵지만 실제로는 일반적입니다.

quicksort의 최악의 경우는 항상 최악의 피벗을 선택하여 파티션 중 하나에 하나의 요소 만 갖도록하는 것입니다. 피벗이 첫 번째 요소 인 경우 (나쁜 선택) 이미 정렬되었거나 역 정렬 된 데이터가 최악의 경우입니다. 모두 동일하거나 첫 번째 또는 마지막이 다른 3 개의 중간 피벗 데이터의 경우 트릭을 수행합니다.


빠른 정렬을 위해서는 평균 복잡도가 nlogn이고 최악의 경우 n ^ 2입니다. 최악의 경우 동작을 트리거 할 가치가있는 이유는 가장 큰 재귀 수준을 생성하는 경우이기도하기 때문입니다. 순진한 구현의 경우 재귀 깊이는 n 일 수 있으며 이는 스택 오버플로를 트리거 할 수 있습니다. 유사한 이유로 다른 극단적 인 상황 (가장 좋은 경우 포함)을 테스트하는 것이 좋습니다.


알다시피, 평균과의 표준 편차가 실제로 분할 결과를 결정합니다.
mrQWERTY

"... 거의 모든 경우에 최악의 경우는 실제로 나쁘기 때문에 테스트 할 가치가 있습니다." . 논쟁의 여지가 있습니다. 이 표를 볼 때 : en.wikipedia.org/wiki/… 나는 대부분의 "좋은"정렬 알고리즘 (즉, 평균 O(NlogN)성능 또는 더 나은)에 대해 최악의 경우와 평균적인 경우가 같은 복잡성을 갖는다는 결론을 내립니다 . 이는 최악의 경우 테스트 할 가치가 없다는 것을 의미합니다. (시험이 아마 O(N)더 나쁘거나 더 나쁘다는 것을 나타냅니다.)
Stephen C

@ Renren29 : 값의 2 또는 3이 동일한 경우에만 3 피벗의 중앙값이 첫 번째 또는 마지막입니다. SD는 들어오지 않습니다.
david.pfx

@StephenC : Quicksort를 포함한 많은 '좋은'알고리즘은 n ^ 2 최악의 경우 복잡성을가집니다. 그러나 편집을 참조하십시오.
david.pfx

@ david.pfx- "일부"... 예. "거의 모든 것"... NO.
Stephen C

0

알고리즘은 파티셔닝의 피벗 및 비대칭 검색과 동일한 연속 요소를 제외하고 무작위 피벗을 사용하여 대부분의 나쁜 경우를 피합니다. 이것은 순방향 요소 검색 크거나 같음을 후방 요소에 피봇 및 검색 미만 피봇.
MichaelT에게 감사합니다. 비대칭 검색은 [2,1,2,1,2,1,2,1]을 해결하기 위해 고안되었습니다.

내 함수 qsort_random ()에 의해 다음 결과가 생성됩니다. N = 100,000

usec    call   compare   copy    pattern
80132   62946  1971278   877143  random
47326   57578  1606067   215155  sorted : 0,1,2,3,...,n-1
49927   63578  1628883   338715  sorted in reverse : n-1,n-2,...,2,1,0
55619   63781  1596934   377330  nearly reverse : n-2,n-1,n-4,n-3,...,2,3,0,1
54714   66667  1611454   290392  median-3-killer : n-1,0,1,2,...,n-2
1491    1      99999     4       all values the same : n,n,n,...
1577    1      99999     4       first is higher : n,1,1,1,...
2778    2      156159    10      last is lower : n,n,n,...,n,1
2994    3      199996    100009  a few data : n,...,n,1,...,1
3196    3      199996    50012   zigzag : n,1,n,1,...,n,1
917796  56284  67721985  673356  valley(sawtooth?) : n-1,n-3,...,0,...,n-4,n-2

대부분의 경우 임의 패턴보다 빠릅니다. 밸리 패턴은 대부분의 피벗 선택에 나쁜 경우입니다.

qsort(3)       usec = 14523   call = 0      compare = 884463    copy = 0
qsort_head()   usec = 138609  call = 99999  compare = 8120991   copy = 1214397
qsort_middle() usec = 664325  call = 99999  compare = 52928111  copy = 1036047
qsort_trad()   usec = 118122  call = 99999  compare = 6476025   copy = 1337523
qsort_random() usec = 295699  call = 58806  compare = 19439952  copy = 732962
qsort_log2()   usec = 66411   call = 63987  compare = 1597455   copy = 944821

qsort_log2 ()는 log2 (N) 요소에서 피벗을 선택하여 잘못된 경우를 피합니다.
qsort (3)은 병합 정렬 색인 정렬 인 GNU 라이브러리를 사용합니다.
qsort_trad ()는 첫 번째, 중간 및 마지막 요소에서 피벗을 선택합니다.
qsort_random () 및 qsort_log2 ()는 스와핑을 사용하지 않습니다.
소스 C 프로그램과 스크립트는 github에 게시되어 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.