2011-06-26 10 views
7

Ten quicksort ma sortować "v [left] ... v [right] do porządku rosnącego"; kopiowane (bez uwag) od C Programming Language przez K & R (Second Edition):Błąd w przykładzie quicksort (książka K & R C)?

void qsort(int v[], int left, int right) 
{ 
    int i, last; 
    void swap(int v[], int i, int j); 

    if (left >= right) 
     return; 
    swap(v, left, (left + right)/2); 
    last = left; 
    for (i = left+1; i <= right; i++) 
     if (v[i] < v[left]) 
      swap(v, ++last, i); 
    swap(v, left, last); 
    qsort(v, left, last-1); 
    qsort(v, last+1, right); 
} 

myślę, że jest to błąd w

(left + right)/2 

Załóżmy lewo = INT_MAX - 1 i prawo = INT_MAX. Czy nie spowoduje to niezdefiniowanego zachowania z powodu przekroczenia liczby całkowitej?

+3

Zostało to prawdopodobnie zaprogramowane z założeniem, że tablica nie byłaby tak duża w czasie wykonywania. :) – sarnold

+0

To bardzo dobre założenie, ponieważ nie masz miejsca w pamięci na Twój program quicksort –

+1

Zobacz także: http://googleresearch.blogspot.com/2006/06/extra-extra-read-all-about-it -nearly.html –

Odpowiedz

7

Tak, masz rację. Możesz użyć numeru left - (left - right)/2, aby uniknąć przepełnienia.

+0

co przepełnia? –

+0

Świetne rozwiązanie !!! – functionptr

+4

@Jerry: ITYM: 'left + (right-left)/2' –

2

Nie wyobrażasz sobie tablicy z INT_MAX liczbą elementów, prawda?

+2

To tylko 8 gigabajtów przestrzeni adresowej, przy założeniu 32-bitowych liczb całkowitych. Więcej niż na nowoczesnym sprzęcie. :) – sarnold

+2

Prawdopodobnie będziemy musieli usprawiedliwić K & R, aby nie brać pod uwagę pamięci rosnącej z KB do GB. A "640k powinno wystarczyć dla wszystkich"? –

+0

@Bo istnieją platformy z 16-bitowymi 'int's, wiesz, i jestem pewien, że niektóre z nich mają więcej niż 64Kb pamięci. 'int'! =' intptr_t'. –

1

Tak, masz rację, chociaż jest to prawdopodobnie napisane tak dla uproszczenia - to przecież przykład, a nie kod produkcyjny.

1

K & R zawsze było trochę zaniedbane z użyciem argumentów unsigned vs signed. Efekt uboczny pracy z PDP, który przypuszczalnie ma tylko 16 kilobajtów pamięci. To zostało naprawione jakiś czas temu. Obecna definicja qsort to:

void qsort(
    void *base, 
    size_t num, 
    size_t width, 
    int (__cdecl *compare)(const void *, const void *) 
); 

Zwróć uwagę na użycie size_t zamiast int. I oczywiście pusta * baza, ponieważ nie wiesz, jakiego rodzaju sortujesz.

+1

Brodawka '__cdecl' nie jest częścią standardowej definicji. – caf

+0

Jestem pewna, że ​​to prawda, prawdopodobnie mieli wtedy tylko jedną * konwencję wywoływania *. I o wiele mniej słów kluczowych, które zaczynały się od * dwóch * podkreśleń. Zostaw to sprzedawcom, aby było to skomplikowane. Koniecznie tak, standardowy rodzaj sux. –