Рекурсия выводит значение счетчика не один раз, а столько, сколько было рекурсивных вызовов - 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 не изменяется в процессе выполнения программы