2014-01-17 3 views
0

내 순진 퀵 알고리즘에 관한 단지 빠른 (하하하) 질문 : 시험 배열의 코드를 실행하면내 quicksort 구현의 문제점은 무엇입니까?

#include <iostream> 

template <class T> 
void quicksort2(T array[] , int start, int end){ 
    int i = start; 
    int j = end; 
    int temp; 
    int pivot = (end - start)/2; 

    // Partioning 
    while(i <= j){ 

    while(array[i] < array[pivot]){ 
     i++; 
    } 
    while(array[j] > array[pivot]){ 
     j--; 
    } 

    if(i <= j){ 
     temp = array[i]; 
     array[i] = array[j]; 
     array[j] = temp; 
     i++; 
     j--; 
    } 
    } 

    // Sorting partions 
    if(start <= j){ 
    quicksort2(array , start , j); 
    } 
    if(end >= i){ 
    quicksort2(array , i , end); 
    } 
} 

, 보인다을 그 배열합니다 (이하 측의 왼쪽)가 정렬되고 오른쪽을 정렬하지 않고 무한 루프를 만듭니다.

코드를 실행하기 전에 약간의 경고가 표시되며 테스트 배열에서 코드를 실행하면 컴퓨터가 정지되는 경우가 있습니다.

어쨌든 도움 주셔서 감사합니다! 또한, 숙제가 아닙니다 (정렬 알고리즘을 사용하여 어떤 방면에서 배트를 배울 필요가 있습니까?)

+1

퀵소트는 영원히 전에 대학에서 고급 알고리즘 수업에서 배운 첫 번째 알고리즘이었습니다. –

+0

당신은 창문을 운영하고 있습니까? –

+3

'temp '를 사용하면 위험합니다. 'temp'는'int'이지만'temp = array [i];의'array [i];'는'T'입니다. [std :: swap'] (http://en.cppreference.com/w/cpp/algorithm/swap)을 사용하는 것이 좋지만 바보 같을 수도 있습니다. 나는 그것을 손으로 10 번, 9 번 그리고 1 번 잘못 썼다. 불쾌한 버그. 'std :: swap (array [i], array [j])'는 트릭을 수행해야하며 이미 템플리트 화되어있다. – luk32

답변

1

질문에 대한 답변을 드리겠습니다.

시작 == 끝 부분에서 메서드가 호출되는 경우를 어떻게 처리합니까?

각 실행마다 피벗 주위에서 하위 섹션을 나눕니다. 따라서 각 재귀 실행에는 마지막 시간 길이의 1/2이 있습니다. 먼저 전반을 정렬 한 다음 처음 1/4을 정렬 한 다음 처음 1/8을 정렬합니다. 결국, start = end = 0 인 메소드를 호출하게됩니다. 0 - 0/2가 0 인 피벗을 만듭니다.

코드를 통해 케이스를 실행하면, 메소드가 자신과 하나의 항목을 정렬하려고하는 경우를 처리합니다. 무한 재귀 루프에서 멈출 때까지 충돌이 발생할 것입니다. ...

스택 오버플로.

+2

또한 피벗 계산이 잘못되었습니다. 시작과 끝이 2와 4 인 경우 4 - 2 = 2/2 = 1입니다. 따라서 피벗 인덱스가 시작, 끝 범위를 벗어납니다. –

+0

또한 내부 루프는 교차점 ('i''''''''''')에 대한 checkng이 아니므로 계속 이동할 수 있습니다. – wmorrison365

+0

@LeeLouviere 피벗 계산이 내가 의미하는 바가 아님. 나는 그것을 (왼쪽 + 오른쪽)/2가되도록 의도했다. 그것을 잡아 주셔서 감사합니다. 이 문제를 수정하고 설명 된 사례를 처리하기위한 코드를 구현 한 후에는 코드가 제대로 작동합니다. 엄청 고마워! –

0

'='을 사용하는 것이 좋습니다. 피벗 포인트와 비교할 때> = 및 < = 사용할 수 있다고 생각하지만 스왑을 수행 할 때는 필요하지 않습니다.

키커는 재귀 호출입니다. =를 사용하고 싶지는 않습니다. 무한 재귀의 원인이라고 생각합니다. 결국 j가 시작보다 작을 수 없으므로 결국 충돌 할 것입니다. 그래서 기본적으로 =와 비교하고, 제거하고, =없이 모든 비교를 추가합니다.

관련 문제