Рекурсия выводит значение счетчика не один раз, а столько, сколько было рекурсивных вызовов - C (СИ)
Формулировка задачи:
Задача состоит в том, чтобы определить, какой метод сортировки быстрее. В одну функцию (SortBalb) я отправляю массив, и он сортируется пузырьком, в другую (QuickSort) отправляю такой же массив, где он сортируется методом быстрой сортировки(Хоара).
Вывожу время сортировки и количество перестановок. Время выводит нормально, тк это просто.
Вот количество итераций - для пузырька - просто, для QuickSort - получается, что срабатывает printf каждый вызов(что тоже естественно и понятно тк имеем рекурсию). Но не красиво.
Как вывести суммарное количество перестановок для рекурсивной функции QuickSort?
Спасибо.
#include <stdio.h> #include <math.h> #include<conio.h> #include<stdlib.h> #include<string.h> #include<Windows.h> #include<time.h> void PrintArray(int*,int); void SortBalb(int*,int); void QuickSort(int*,int); void main() { int n,*arr,*arrForBalb,*arrForQuick; SetConsoleCP(1251); SetConsoleOutputCP(1251); srand(time(NULL)); //puts("Введите размерность массива: "); //scanf("%d",&n); n=10000; arr=new int[n]; arrForBalb=new int[n]; arrForQuick=new int[n]; for(int i=0;i<n;i++) { *(arr+i)=rand()%100; *(arrForBalb+i)=*(arr+i); //Сразу сохраню сгенеренный массив в массивы, над которыми будем издеваться *(arrForQuick+i)=*(arr+i); } //printf("Сгенерированный массив: \n"); //PrintArray(arr,n); printf("\n"); SortBalb(arrForQuick,n); //Издеваемся методом пузырька //printf("Отсортированный массив: \n"); //PrintArray(arrForModify,n); printf("\n"); clock_t timeQuickSort=clock(); QuickSort(arrForQuick,n-1); //Издеваемся методом Хоара timeQuickSort=clock()-timeQuickSort; printf("\nВремя перестановок сортировкой Хоара: %lf секунд \n",(float)timeQuickSort/CLOCKS_PER_SEC); _getch(); } void PrintArray(int*a,int n) { for(int i=0;i<n;i++) printf("%d, ",*(a+i)); } void SortBalb(int*a,int n) { int temp,countChange=0; clock_t timeBalb=clock(); for(int i=0;i<n;i++) for(int j=0;j<n-1;j++) if(*(a+j)>*(a+j+1)) { temp=*(a+j+1); *(a+j+1)=*(a+j); *(a+j)=temp; countChange++; } timeBalb=clock()-timeBalb; printf("\nВремя перестановок сортировкой обмена: %lf секунд \n",(float)timeBalb/CLOCKS_PER_SEC); //printf("\nКолличество перестановок: %d\n",countChange); } void QuickSort(int*a,int n) { int countChangeQuick=0,countChangeQuickTemp=0; int sizeForChange=n,left=0,temp; int pivot=*(a+(int)(n/2)); do { while(*(a+left)<pivot) left++; while(*(a+n)>pivot) n--; if(left<=n) { temp=*(a+left); *(a+left)=*(a+n); *(a+n)=temp; left++; n--; countChangeQuick++; } }while(left<=n); if(n>0) QuickSort(a,n); if(sizeForChange>left) QuickSort(a+left,sizeForChange-left); printf("\nКолличество перестановок: %d\n",countChangeQuick); }
Решение задачи: «Рекурсия выводит значение счетчика не один раз, а столько, сколько было рекурсивных вызовов»
textual
Листинг программы
#include<windows.h> #include<time.h> #include<stdio.h> #include<conio.h> void PrintArray(int*,int); void SortBalb(int*,int); void QuickSort(int*,int,int*); void main() { int n,*arr,*arrForBalb,*arrForQuick; int countChangeQuick=0,countChangeQuickTemp=0; SetConsoleCP(1251); SetConsoleOutputCP(1251); srand(time(NULL)); // puts("Введите размерность массива: "); // scanf("%d",&n); n=10; arr=new int[n]; arrForBalb=new int[n]; arrForQuick=new int[n]; for(int i=0;i<n;i++) { *(arr+i)=rand()%100; *(arrForBalb+i)=*(arr+i); //Сразу сохраню сгенерированный массив в массивы, над которыми будем издеваться *(arrForQuick+i)=*(arr+i); } //printf("Сгенерированный массив: \n"); //PrintArray(arr,n); printf("\n"); SortBalb(arrForQuick,n); //Издеваемся методом пузырька //printf("Отсортированный массив: \n"); //PrintArray(arrForModify,n); printf("\n"); clock_t timeQuickSort=clock(); QuickSort(arrForQuick,n-1,&countChangeQuick); //Издеваемся методом Хоара timeQuickSort=clock()-timeQuickSort; printf("\nВремя перестановок сортировкой Хоара: %lf секунд \n",(float)timeQuickSort/CLOCKS_PER_SEC); printf("\nКоличество перестановок быстрой сортировкой: %d\n",countChangeQuick); _getch(); } void PrintArray(int*a,int n) { for(int i=0;i<n;i++) printf("%d, ",*(a+i)); } void SortBalb(int*a,int n) { int temp,countChange=0; clock_t timeBalb=clock(); for(int i=0;i<n;i++) for(int j=0;j<n-1;j++) if(*(a+j)>*(a+j+1)) { temp=*(a+j+1); *(a+j+1)=*(a+j); *(a+j)=temp; countChange++; } timeBalb=clock()-timeBalb; printf("\nВремя перестановок сортировкой обмена: %lf секунд \n",(float)timeBalb/CLOCKS_PER_SEC); printf("\nКоличество перестановок: %d\n",countChange); } void QuickSort(int*a,int n,int *pcountChangeQuick) { int sizeForChange=n,left=0,temp; int pivot=*(a+(int)(n/2)); do { while(*(a+left)<pivot) left++; while(*(a+n)>pivot) n--; if(left<=n) { temp=*(a+left); *(a+left)=*(a+n); *(a+n)=temp; left++; n--; ++(*pcountChangeQuick); } }while(left<=n); if(n>0) QuickSort(a,n,pcountChangeQuick); if(sizeForChange>left) QuickSort(a+left,sizeForChange-left,pcountChangeQuick); }
Объяснение кода листинга программы
- Объявлены функции:
- PrintArray(int*,int)
- SortBalb(int*,int)
- QuickSort(int,int,int)
- main()
- В функции main() объявлены и инициализированы переменные:
- n (размер массива)
- arr (массив для сортировки)
- arrForBalb (массив для сортировки методом пузырька)
- arrForQuick (массив для сортировки методом Хоара)
- countChangeQuick (счетчик перестановок быстрой сортировки)
- countChangeQuickTemp (временная переменная для подсчета перестановок в рекурсивных вызовах быстрой сортировки)
- timeQuickSort (время выполнения быстрой сортировки)
- В функции main() выполнены следующие действия:
- Выполнен проход по массиву и заполнен массив arrForBalb значениями из arr
- Выполнен проход по массиву и заполнен массив arrForQuick значениями из arr
- Выполнен проход по массиву и отсортирован массив arrForBalb методом пузырька
- Выполнен проход по массиву и отсортирован массив arrForQuick методом Хоара
- Вычислено время выполнения быстрой сортировки
- Выведено количество перестановок быстрой сортировки
- В функции SortBalb() объявлены переменные:
- temp (временная переменная для обмена значениями)
- countChange (счетчик перестановок при сортировке методом обмена)
- timeBalb (время выполнения сортировки методом обмена)
- В функции QuickSort() объявлены переменные:
- sizeForChange (размер сортируемого массива)
- left (левая граница сортируемого массива)
- n (правая граница сортируемого массива)
- pivot (опорный элемент для разделения массива)
- temp (временная переменная для обмена значениями)
- *pcountChangeQuick (указатель на переменную countChangeQuick)
- В функции QuickSort() выполнены следующие действия:
- Выполнен рекурсивный вызов QuickSort() для сортировки правой части массива
- Выполнен рекурсивный вызов QuickSort() для сортировки левой части массива
- Если left<=n, выполнен обмен значениями и увеличены left и n
- Увеличено значение *pcountChangeQuick
- В функции main() выполнено 4 рекурсивных вызова QuickSort()
- Первые два вызова используют arrForQuick в качестве входного массива
- Третий вызов использует arrForBalb в качестве входного массива
- Четвертый вызов использует arr в качестве входного массива
- В функции main() выведено значение countChangeQuick, которое увеличивается на 1 при каждом рекурсивном вызове QuickSort()
- Значение countChangeQuickTemp не используется в коде
- Значение timeQuickSort вычисляется только один раз, независимо от количества рекурсивных вызовов
- Значение n не изменяется в процессе выполнения программы
- Значение arr не изменяется в процессе выполнения программы
- Значение arrForBalb не изменяется в процессе выполнения программы
- Значение arrForQuick не изменяется в процессе выполнения программы
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д