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