Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Рацеев С.М. Программирование на языке Си.pdf
Скачиваний:
369
Добавлен:
23.03.2016
Размер:
1.65 Mб
Скачать

Приложение 3. СОРТИРОВКА ИНДЕКСОВ И УКАЗАТЕЛЕЙ

Иногда требуется отсортировать не сам массив (например, массив строк, массив структур), а лишь массив индексов (или указателей) и, обращаясь к исходному массиву через массив индексов, иметь данные в отсортированном виде.

Для наглядности рассмотрим массив действительных чисел a. Требуется записать индексы массива a в массив индексов ind (такого же размера, что и массив a) в том порядке, в котором соответствующие им элементы образуют возрастающую последовательность, причем порядок следования элементов в массиве a должен остаться прежним. Например, если массив a состоит из элементов

30, 10, 20, 50, 40,

то массив ind будет состоять из таких элементов:

1, 2, 0, 4, 3.

Для решения данной задачи можно использовать алгоритмы сортировок из приложения 2 с той модификацией, что в данном случае следует переставлять не сами элементы массива a, а переставлять соответствующие данным элементам индексы в массиве ind.

1. Сортировка индексов на основе метода прямого выбора

#include<stdio.h> #define N 10

/* вывод на экран элементов массива a через массив ind */ void PrintThroughIndex(double *a, int *ind, int n)

{

int i;

for(i = 0; i < n; i++) printf("%4.0f ", a[ind[i]]);

printf("\n");

}

/* сортировка индексов на основе метода прямого выбора*/

315

void SelectionSortIndex(const double *a, int *ind, const int n)

{

int i, j, k, buf; double min;

/* пусть изначальное расположение индексов в массиве ind соответствует порядку следования элементов массива a:

*/

for(i = 0; i < n; i++) ind[i] = i;

for(i = 0; i < n-1; i++)

{

k = i;

min = a[ind[i]];

for(j = i + 1; j < n; j++) if (a[ind[j]] < min)

{

k = j;

min = a[ind[j]];

}

buf = ind[k]; ind[k] = ind[i]; ind[i] = buf;

}

}

int main()

{

double a[N]; /* исходный массив */ int ind[N]; /* массив индексов */ …/* заполнение массива a */

SelectionSortIndex(a, ind, N); /* сортировка индексов */

/*вывод массива a в порядке возрастания через массив ind:*/

PrintThroughIndex(a, ind, N); return 0;

}

316

2. Сортировка индексов на основе пузырьковой сортировки

void BubbleSortIndex(const double *a, int *ind, const int n)

{

int i, j, r, flag, buf; for(i = 0; i < n; i++)

ind[i] = i; r = n;

do

{

flag = 0;

for(i = 1; i < r; i++)

if (a[ind[i]] < a[ind[i-1]])

{

buf = ind[i]; ind[i] = ind[i-1]; ind[i-1] = buf; flag = 1;

}

r--; }while(flag);

}

3. Сортировка индексов на основе быстрой сортировки

void QuickSortIndex (const double *a, int *ind, int left, int right)

{

int i, j, buf; double x; i = left;

j = right;

x = a[ind[(left + right)/2]]; do

{

while (a[ind[i]] < x) i++;

317

while (x < a[ind[j]]) j--;

if (i <= j)

{

buf = ind[i]; ind[i] = ind[j]; ind[j] = buf; i++;

j--;

}

} while( i <= j);

if (left < j) QuickSortIndex (a, ind, left, j); if (right > i) QuickSortIndex (a, ind, i, right);

}

int main()

{

double a[N]; int i, ind[N];

…/* заполнение массива a */ for(i = 0; i < N; i++)

ind[i] = i; QuickSortIndex(a, ind, 0, N-1); return 0;

}

Если массив a является глобальным, то в этом случае можно также использовать встроенную функцию qsort() из библиотеки <stdlib.h> следующим образом:

#include<stdlib.h> #define N 10

double a[N]; /* глобальный массив a */

int compare(const void *p1, const void *p2)

{

318