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

Объяснение кода листинга программы

  1. Объявлены функции:
    • PrintArray(int*,int)
    • SortBalb(int*,int)
    • QuickSort(int,int,int)
    • main()
  2. В функции main() объявлены и инициализированы переменные:
    • n (размер массива)
    • arr (массив для сортировки)
    • arrForBalb (массив для сортировки методом пузырька)
    • arrForQuick (массив для сортировки методом Хоара)
    • countChangeQuick (счетчик перестановок быстрой сортировки)
    • countChangeQuickTemp (временная переменная для подсчета перестановок в рекурсивных вызовах быстрой сортировки)
    • timeQuickSort (время выполнения быстрой сортировки)
  3. В функции main() выполнены следующие действия:
    • Выполнен проход по массиву и заполнен массив arrForBalb значениями из arr
    • Выполнен проход по массиву и заполнен массив arrForQuick значениями из arr
    • Выполнен проход по массиву и отсортирован массив arrForBalb методом пузырька
    • Выполнен проход по массиву и отсортирован массив arrForQuick методом Хоара
    • Вычислено время выполнения быстрой сортировки
    • Выведено количество перестановок быстрой сортировки
  4. В функции SortBalb() объявлены переменные:
    • temp (временная переменная для обмена значениями)
    • countChange (счетчик перестановок при сортировке методом обмена)
    • timeBalb (время выполнения сортировки методом обмена)
  5. В функции QuickSort() объявлены переменные:
    • sizeForChange (размер сортируемого массива)
    • left (левая граница сортируемого массива)
    • n (правая граница сортируемого массива)
    • pivot (опорный элемент для разделения массива)
    • temp (временная переменная для обмена значениями)
    • *pcountChangeQuick (указатель на переменную countChangeQuick)
  6. В функции QuickSort() выполнены следующие действия:
    • Выполнен рекурсивный вызов QuickSort() для сортировки правой части массива
    • Выполнен рекурсивный вызов QuickSort() для сортировки левой части массива
    • Если left<=n, выполнен обмен значениями и увеличены left и n
    • Увеличено значение *pcountChangeQuick
  7. В функции main() выполнено 4 рекурсивных вызова QuickSort()
    • Первые два вызова используют arrForQuick в качестве входного массива
    • Третий вызов использует arrForBalb в качестве входного массива
    • Четвертый вызов использует arr в качестве входного массива
  8. В функции main() выведено значение countChangeQuick, которое увеличивается на 1 при каждом рекурсивном вызове QuickSort()
  9. Значение countChangeQuickTemp не используется в коде
  10. Значение timeQuickSort вычисляется только один раз, независимо от количества рекурсивных вызовов
  11. Значение n не изменяется в процессе выполнения программы
  12. Значение arr не изменяется в процессе выполнения программы
  13. Значение arrForBalb не изменяется в процессе выполнения программы
  14. Значение arrForQuick не изменяется в процессе выполнения программы

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

6   голосов , оценка 4 из 5
Похожие ответы