2015-01-09 3 views
-3

Я пытаюсь отсортировать массив из 10 целых чисел, используя алгоритм Quicksort, это ниже мой код, он не сортируется должным образом, может кто-то может указать мне на возможные ошибки, которые я делаю?Быстрое сортирование массива в C

int partition(int arr[], int first, int last) 
{ 
    int pivot = arr[first]; 
    int low = first; 
    int i = first + 1; 
    while(i <= last){ 
     if(arr[i] < pivot){ 
      low++; 
      swap(&arr[i], &arr[low]); 
     } 
     i++; 
    } 
    swap(&arr[first], &arr[low]); 
    return low; 
} 

void quick_sort(int arr[], int first, int last) 
{ 
    int pivot_pos; 
    if(first < last){ 
     pivot_pos = partition(arr, first, last); 
     quick_sort(arr, first, pivot_pos-1); 
     quick_sort(arr, pivot_pos+1, last); 
    } 
} 
+0

Опишите свою проблему четко. Не отправляйте код и ожидайте, что люди исправит его для вас. – ale64bit

+1

почему вы отметили как c, так и C++? btw я могу скомпилировать его! – chouaib

+0

Возможно, вы захотите просмотреть [Quicksort: Выбор стержня] (http://stackoverflow.com/questions/164163/quicksort-choosing-the-pivot/164183#164183), хотя вы можете обнаружить, что немного до сложного (или сложнее, чем вам нужно). Какую диагностическую печать вы сделали? Вы проверили значения элемента раздела и последнего и первого и т. Д.? Вы не указали код для 'swap()'; вы знаете, работает ли это правильно? –

ответ

0

На основе вашего кода функция qsort отлично подходит даже для раздела, который немного сложно понять! Я думаю, ваша проблема связана с функцией обмена! Вот рабочий код, который использует простую для понимания реализации функции распределения:

void swap(int *a, int *b) 
{ 
    int temp; 
    temp=*a; 
    *a=*b; 
    *b=temp; 
} 


/* the aim of the partition is to return the subscript of the exact */ 
/* position of the pivot when it is sorted */ 
// the low variable is used to point to the position of the next lowest element 
int partition(int arr[], int first, int last) 
{ 
    int pivot = arr[last]; // changed the pivot 
    int low = first; 
    int i = first; // changed 
    while(i <= last-1){// or you can do for(i=first;i<last;i++) 
     if(arr[i] < pivot){ 
      swap(&arr[i], &arr[low]); 
      low++; 
     } 
     i++; 
    } 
    swap(&arr[last], &arr[low]); 
    // after finishing putting all the lower element than the pivot 
    // It's time to put the pivot into its place and return its position 
    return low; 
} 



void quick_sort(int arr[], int first, int last) 
{ 
    int pivot_pos; 
    if(first < last){ 
     pivot_pos = partition(arr, first, last); 
     quick_sort(arr, first, pivot_pos-1); 
     quick_sort(arr, pivot_pos+1, last); 
    } 
} 

Чтобы протестировать программу, которую вы можете использовать основную функцию ниже

int main(int argc, char *argv[]) 
{ 
    int tab[]={4,53,5,6,7,1}; 
    quick_sort(tab,0,5); 
    int i=0; 
    for (i=0;i<6;i++) 
    { 
     printf(" %d ",tab[i]); 
    } 
    printf("\n"); 

    return 0; 
} 

он будет генерировать отсортированный массив

1 4 5 6 7 53 

Если вы хотите увидеть, что произошло именно здесь полный код :)

#include <stdio.h> 

void affiche(int *p,int size); 
void swap(int *p, int a, int b) 
{ 
    int temp=p[a]; 
     p[a]=p[b]; 
    p[b]=temp; 
} 

int partition(int *p, int start, int end) 
{ 
    int pindex=start; 
    int pivot=p[end]; 
    int i=0; 
    for (i=start;i<=end-1;i++) 
    { 
     if (p[i]<pivot) 
     { 
      printf("swap p[%d] and p[%d] pivot %d\n",i,pindex,pivot); 
      swap(p,i,pindex); 
      affiche(p,7); 
      pindex++; 
     } 
    } 
      printf("==>swap p[%d] and p[%d] pivot %d\n",pindex,end,pivot); 
    swap(p,pindex,end); 
    return pindex; 
} 
void quicksort(int *p,int a,int b) 
{ 
    if (a<b) 
    { 
     affiche(p,7); 
     int pindex=partition(p,a,b); 
     quicksort(p,a,pindex-1); 
     quicksort(p,pindex+1,b); 
    } 
} 

void affiche(int *p,int size) 
{ 
int i=0; 
for (i=0;i<size;i++) 
{ 
    printf(" %d ",p[i]); 
} 
printf("\n"); 

} 
int main(int argc, char *argv[]) 
{ 
    int tab[]={7,2,4,8,4,0,4}; 
    affiche(tab,7); 
    quicksort(tab,0,6); 
    affiche(tab,7); 

    return 0; 
} 
+1

Любопытно: я обнаружил, что исходная функция раздела работает нормально. –

+0

извините за поздний ответ: да, вы правы @ JonathanLeffler, его код кажется работоспособным! Я думаю, у него есть проблема с функцией подкачки! Более того, раздел действительно трудно понять по сравнению с обычным! –

2

Здесь представлена ​​инструментальная версия вашего кода. Поскольку вы не указали функцию swap(), я написал это; Я также написал dump_data() для печати содержимого сегмента массива и main() для тестирования. На основании ограниченного тестирования, которое я сделал, сортировка работает. Учитывая, что вы говорите, что это не так, я подозреваю, что ваш код swap() может быть неисправен; либо это, либо ваш тестовый код жгута неисправен (или мой тест просто случается так, как работает!).

#include <stdio.h> 

static inline void swap(int *a, int *b) { int c = *a; *a = *b; *b = c; } 

static void dump_data(const char *tag, int *data, int first, int last) 
{ 
    printf("%s: (%d:%d)\n", tag, first, last); 
    for (int i = first; i <= last; i++) 
     printf(" %d", data[i]); 
    putchar('\n'); 
} 

static 
int partition(int arr[], int first, int last) 
{ 
    int pivot = arr[first]; 
    int low = first; 
    int i = first + 1; 
    while (i <= last) 
    { 
     if (arr[i] < pivot) 
     { 
      low++; 
      swap(&arr[i], &arr[low]); 
     } 
     i++; 
    } 
    swap(&arr[first], &arr[low]); 
    return low; 
} 

static 
void quick_sort(int arr[], int first, int last) 
{ 
    if (first < last) 
    { 
     dump_data("-->> QS", arr, first, last); 
     int pivot_pos = partition(arr, first, last); 
     printf("Pivot: arr[%d] = %d\n", pivot_pos, arr[pivot_pos]); 
     quick_sort(arr, first, pivot_pos - 1); 
     dump_data("-1-- QS", arr, first, pivot_pos - 1); 
     quick_sort(arr, pivot_pos + 1, last); 
     dump_data("-2-- QS", arr, pivot_pos + 1, last); 
     dump_data("<<-- QS", arr, first, last); 
    } 
} 

int main(void) 
{ 
    int data[] = { 9, 2, 4, 7, 1, 3, 8, 6, 5 }; 
    int size = sizeof(data)/sizeof(data[0]); 
    dump_data("Before", data, 0, size - 1); 
    quick_sort(data, 0, size - 1); 
    dump_data("After", data, 0, size - 1); 
    return 0; 
} 

Пример запуск:

Before: (0:8) 
9 2 4 7 1 3 8 6 5 
-->> QS: (0:8) 
9 2 4 7 1 3 8 6 5 
Pivot: arr[8] = 9 
-->> QS: (0:7) 
5 2 4 7 1 3 8 6 
Pivot: arr[4] = 5 
-->> QS: (0:3) 
3 2 4 1 
Pivot: arr[2] = 3 
-->> QS: (0:1) 
1 2 
Pivot: arr[0] = 1 
-1-- QS: (0:-1) 

-2-- QS: (1:1) 
2 
<<-- QS: (0:1) 
1 2 
-1-- QS: (0:1) 
1 2 
-2-- QS: (3:3) 
4 
<<-- QS: (0:3) 
1 2 3 4 
-1-- QS: (0:3) 
1 2 3 4 
-->> QS: (5:7) 
7 8 6 
Pivot: arr[6] = 7 
-1-- QS: (5:5) 
6 
-2-- QS: (7:7) 
8 
<<-- QS: (5:7) 
6 7 8 
-2-- QS: (5:7) 
6 7 8 
<<-- QS: (0:7) 
1 2 3 4 5 6 7 8 
-1-- QS: (0:7) 
1 2 3 4 5 6 7 8 
-2-- QS: (9:8) 

<<-- QS: (0:8) 
1 2 3 4 5 6 7 8 9 
After: (0:8) 
1 2 3 4 5 6 7 8 9 

Более тщательное тестирование будет автоматически проверять, что результат на самом деле отсортирован, а также имеет больший массив с фиктивными элементами, что после сортировки проверки гарантирует не было изменено и будет иметь несколько тестовых прогонов разных размеров (включая 0, 1, 2, 3, 4, а затем несколько более крупных размеров). Это просто проверяет правильность. Для проверки производительности вы делаете такие вещи, как проверенные уже отсортированные данные или все значения одинаковые или обратные отсортированные данные, или органотрубные образования (как форма ∧, так и ∨) и т. Д. С и без повторений в данных (а также случайные последовательности).

Смежные вопросы