Сортировка массивов.
Сортировка данных имеет огромное значение.
// программа 4.16 сортирует элементы массива в возрастающем порядке
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
int main ()
{
setlocale(LC_ALL, "rus");
const int arraySize = 10;
int a [arraySize] = {2, 6, 4, 8, 10, 12, 89, 68, 45, 37};
int i, hold;
cout << "элементы"<<endl;
//вывод исходного массива
for (i = 0; i < arraySize; i++)
cout << setw(4)<< a[i];
//пузырьковая сортировка
//цикл контролирует число проходов
for (int pass = 0; pass < arraySize - 1; pass++)
//один проход
for (int j = 0; j < arraySize - 1; j++)
//одно сравнение
//одна перестановка
if (a[j] > a[ j + 1 ])
{hold = a[j];
a[j] = a[ j + 1 ];
a[ j + 1 ] = hold;
} // конец if
cout << "\n элементы возрастают\n";
for ( int k = 0; k < arraySize; k++)
cout << setw (4) << a[k];
cout << endl;
return 0; //успешное завершение
} // конец main
Программа на рис.4.16 сортирует значения массива a из 10 элементов в возрастающем порядке. Используемая при этом техника, получила название пузырьковая сортировка или сортировка погружением. Потому что наименьшее значение постепенно «всплывает», продвигаясь к вершине (началу) массива, подобно пузырьку воздуха в воде, а наибольшее значение погружается на дно (конец) массива. Этот прием требует нескольких проходов по массиву. При каждом проходе сравнивается пара следующих друг за другом элементов. Если пара расположена в возрастающем порядке или элементы одинаковы, то мы оставляем значения как есть. Если же пара расположена в убывающем порядке, то значения в массиве меняются местами.
Сортировка выполняется с помощью вложенного цикла for.
Если необходима перестановка, она выполняется тремя присваиваниями.
hold = a[i];
a[i] = a[i+1];
a[i+1] = hold;
где дополнительная переменная hold временно хранит одно из двух переставляемых значений. Перестановку нельзя выполнить двумя присваиваниями
a[i] = a[i+1];
a[i+1] = a[i];
Если, например, a[i] равно 7, а a[i + 1] равно 5, то после первого присваивания оба значения будут 5, а значение 7 будет потеряно. Следовательно, необходима дополнительная переменная.
Главное достоинство пузырьковой сортировки заключается в простоте ее программирования.
Однако пузырьковая сортировка выполняется медленно. Это очень заметно при сортировке больших массивов. В задачах вы разработаете более эффективные варианты пузырьковой сортировки.
Поиск в массивах. Линейный поиск и двоичный поиск.
Процесс нахождения какого-то элемента массива называется поиском.
Линейный поиск (рис.4.19) сравнивает каждый элемент массива с ключом поиска. Так как массив не упорядочен, то в среднем, программа должна сравнить с ключом поиска половину элементов массива.
Метод линейного поиска хорошо работает для небольших или для несортированных массивов. Для больших массивов линейный поиск неэффективен. Если массив отсортирован, можно использовать метод двоичного поиска.
Алгоритм двоичного поиска (рис.4.20) исключает половину еще непроверенных элементов массива после каждого сравнения. Алгоритм определяет местоположение среднего элемента массива и сравнивает его с ключом поиска. Если они равны, то ключ поиска найден и выдается индекс этого элемента. В противном случае задача сокращается на половину элементов массива. Если ключ поиска меньше, чем средний элемент массива, то дальнейший поиск осуществляется в первой половине массива (если массив был упорядочен по возрастанию), а если больше, то во второй половине. Поиск продолжается до тех пор, пока ключ поиска не станет равным среднему элементу или пока оставшийся подмассив содержит хотя бы один элемент, не равный ключу поиска.
В наихудшем случае двоичный поиск в массиве из 1024 элементов потребует только 10 сравнений.
Многомерные массивы
Массивы в С++ могут иметь много индексов. Обычным представлением многомерных массивов являются таблицы значений, содержащие информацию в строках и столбцах. Чтобы определить отдельный табличный элемент, нужно указать два индекса: первый (по соглашению) указывает номер строки, а второй (по соглашению) указывает номер столбца. Таблицы или массивы, которые требуют двух индексов для указания отдельного элемента, называются двумерными массивами. Компиляторы С++ поддерживают по меньшей мере 12-мерные массивы.
На рис.4.21 показан двумерный массив а. Каждый элемент массива а определяется именем элемента в форме a[i] [j].
a– это имя массива, i и j – индексы, которые однозначно определяют каждый элемент в а.
Многомерные массивы могут получать начальные значения в своих объявлениях. Например, двумерный массив b[2] [2] можно объявить и дать ему начальные значения с помощью оператора
int b[2] [2] = { {1,2},{3,4} };
или
int b[2] [2] = { {1, },{3,4} };
если начальных значений не хватает, то оставшиеся получают нулевые начальные значения. В начале и в середине нулевые значения надо указывать.
Рис.4.22 демонстрирует присваивание начальных значений двумерным массивам в объявлении.
Размерность первого индекса многомерного массива можно не указывать, но все последующие размерности индексов необходимы.
// рис.4.22
#include "stdafx.h"
#include <iostream>
using namespace std;
void printArray(int [][3]);
int _tmain(int argc, _TCHAR* argv[])
{
int array1 [2][3]= {{1,2,3},{4,5,6}},
array2 [2][3]= {1,2,3,4,5},
array3 [2][3]={{1,2},{4}};
setlocale(LC_ALL, "rus");
cout<<"Значение массива array1 по строкам:"<<endl;
printArray(array1);
cout<<"Значение массива array2 по строкам:"<<endl;
printArray(array2);
cout<<"Значение массива array3 по строкам:"<<endl;
printArray(array3);
return 0;
}
void printArray(int a[][3])
{
for(int i=0; i<=1; i++)
{
for(int j=0;j<=2; j++)
cout<< a[i][j]<<" ";
cout<<endl;
}
}
