Объяснить пару строк по сортировке

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
prikolist
Сообщения: 38
Зарегистрирован: 19 ноя 2008, 13:09

Всем привет! Продолжаю изучать сортировку,возникло пару вопросов, вначале покажу исходник

Код: Выделить всё

#include <iostream>
using namespace std;

//создается шаблнная функция
template<class T> 
// функция принимает аргументы: 
// массив (так как функция шаблонная, то любого типа массив), и кол-во элементов массива.
void quickSortR(T* a, long N) 
{
    long i = 0, j = N;
    // T - это тип передаваемого массива
    // создаем две перменных этого типа
    T temp, p;

  
    p = a[ N>>1 ];

    // процедура разделения (разделяет массив на подмассивы)

    do {
		 
        while ( a[i] < p ) i++;  
        while ( a[j] > p ) j--;  

        if (i <= j) 
        {
            // обмен местами элементов a[i] с a[j] 
            // то есть, то что было в a[i] станет в a[j]
            // а то, что было в a[j] станет в a[i]
            temp = a[i]; a[i] = a[j]; a[j] = temp; 
            i++; j--;
        }
    } while ( i<=j );

    // рекурсивные вызовы, если есть, что сортировать
    if ( j > 0 ) quickSortR(a, j); // рекурсивно вызываем функцию
    if ( N > i ) quickSortR(a+i, N-i); // рекурсивно вызываем функцию
      
}
// ------------------------------------------------------------------------------
int main()
{
  setlocale(LC_ALL, "Russian");   // создаем массив символов
    char str[] = "бвгда";
    // сортируем массив символов
    quickSortR(str, strlen(str));
    // выводим на экран отсортированный массив симовлов
    cout << str <<  endl;
    // создаем целочисленный массив
    int a[] = {50, 7, 3, 9, 25, 33, -5};
    // сортируем целочисленный массив
    quickSortR(a, 6);
    // выводим на экран отсортированный целочисленный массив
    for(int i = 0; i < 7; i++)
        cout << a[i] << " ";
    cout <<  endl;
    
    system("pause"); 
    return 0; // функция main ДОЛЖНА возвращать число
}


Сейчас растолкую часть шаблонной функции, которую я понимаю, а то что не ясно,я спрошу.
Начну, сначала:


Создаётся шаблонная функция с 2 параметрами, 1 - парметр указатель на масив, 2 - ой - количество элементов масива. Создаём 2 переменные шаблонного типа temp, p. Переменной p присваиваем центральный элемент масива. Далее, начинается сам алгоритм:

Возьмём числа какие мы имеем в масиве.

Код: Выделить всё

[B] 50, 7, 3, 9, 25, 33, -5 [/B]

p = 9, i = 0, j = 6

Код: Выделить всё


1) while(a[i]<p) i++;
50<p? НЕТ i осталось 0;

while(a[i]>p) j--;
-5>p? Нет j осталось 6.

Код: Выделить всё


2)if (i <= j)
        {
            temp = a[i]; a[i] = a[j]; a[j] = temp;
            i++; j--;
        }
Если i меньше чем j(тоесть если мы нашли такие элементы,которые заставили предыдущие циклы остановится, то меняем местами a[i], a[j] ;
i = 0; j = 6;
Меняем a[0] = 50, a[6] = -5/

-5   7   3    9    25     33    50


Увеличиваем i  на один, j уменьшаем на один.

Код: Выделить всё


3) i = 1,  j = 5;
 while(a[i]<p) i++;
7<9? Да.  i стаёт равно = 2;

while(a[j]>p) j--;
33>9? Да. j стаёт равно 4

Результат счётчиков i = 2,  j = 4;

Код: Выделить всё

4)while(a[i]<p) i++;
3<9? Да  i = 3;

5) while(a[j]>p) j--;

25>9? Да. j = 3;

Результат i = 3;  j  = 3; 

Как заканчивается цикл do ..while ?
Меня интересует место: while(i < = j) От куда подставляется в i и j?
ДАльше после этого идёт рекурсия, объясните пожалуйста,каким образом идёт подсчёт? Не ясны полностью вот эти 2 строки,на примере с теми числами:

Код: Выделить всё

 if ( j > 0 ) quickSortR(a, j); 
    if ( N > i ) quickSortR(a+i, N-i); 
      
Очень нужно понять. Благодарю.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Если массив Си-шный, т.е. индексирование идет от 0 до (длина минус 1), то строка:
long j = N;
некорректна, т.к. элемента a [N] в массиве не существует.
Видимо, следует писать:
long j = N-1;

Собсственно, в рассматриваемом далее примере так и происходит. При длине массива 7, тем не менее написано j = 6.

Между шагами 3) и 4) примера не выполнена перестановка a и a [j].
Т.е. перед шагом 4) последовательность элементов, как я понимаю, будет:

-5, 7, 25, 9, 3, 33, 50
prikolist
Сообщения: 38
Зарегистрирован: 19 ноя 2008, 13:09

Опишите пожалуйста именно с этими числами, а не с другими,так как я исследую код полностью, именно с этими числами.
Вот числа:

Код: Выделить всё

50, 7, 3, 9, 25, 33, -5
Когда закончатся действия предыдущих циклов, мы перейдём к вот этому:

Код: Выделить всё

if ( j > 0 ) quickSortR(a, j);
    if ( N > i ) quickSortR(a+i, N-i);


Когда мы дошли до этого, как числа будут сортироваться, и какие они будут,когда мы дошли до этого куска. Напишите,что за первым разом, за вторым,чисел не много. Благодарю.
--------------------------------------------------------------------------------
Добавлено сообщение
--------------------------------------------------------------------------------
Скажите,условие:

Код: Выделить всё

if (i <= j) 
        {
            temp = a[i]; a[i] = a[j]; a[j] = temp; 
            i++; j--;
        }
Выполняется,только в случае,если нашлось одно из чисел которые не соответствуют условию вайл?
Ответить