Алгоритмические основы информатики. Учебное пособие
.pdfpreobraz(a,n);
cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n){
for (int i=0;i<=n/2;i++) swap(a[i],a[n-1-i]);
}
Ниже приведены наиболее популярные алгоритмы сортировки и преобразования массивов.
Сортировка (упорядочивание) массива. Процесс упорядочивания информации по определенному признаку называетсясортировкой.
Сортировка – это перестановка элементов массива с целью расположения этих элементов в определённом порядке, например: по возрастанию или по убыванию.
Для чего упорядочивают массивы? Как правило, сортировка не является самоцелью. В упорядоченном массиве, прежде всего, быстрее (и часто проще) искать необходимую информацию.
Существует большое количество методов сортировки и алгоритмов их реализации, например, «пузырьковая» сортировка, метод Шелла, пирамидальная сортировка, быстрая сортировка Хоара и т. д. Для упорядочивания небольших массивов подойдёт любой метод (та же «пузырьковая» сортировка), если же массивы огромны, то требуется более эффективные методы. Одним из лучших по скорости работы считается метод быстрой сортировки Хоара.
51
Здесь разберём один из наиболее простых методов («пузырьковая» сортировка).
Для решения задачи используем один из наиболее простых – метод обменов (или пузырьковый метод). Он основывается на сравнении пары соседних элементов. Если расположение элементов не удовлетворяет условиям сортировки, то их меняют местами. Сравнение и перестановки продолжаются до тех пор, пока не будут упорядочены все элементы. Определить, что элементы упорядочены, можно, фиксируя факт перестановки присваиванием некоторой переменной (n) значения, например, true. До начала сравнения элементов эта переменная должна иметь другое значение, например, false. Если после сравнения всех элементов значение переменной остается равным false, то это означает, что все элементы упорядочены.
Пример 4. Выполнить сортировку методом пузырька целочисленного массива.
Пояснения. При реализации алгоритма пузырьковым методом последовательно сравниваем a[0] с a[1], затем a[1] с a[2] и так далее, меняя местами a[i] c a[i+1], если a[i]>a[i+1]. Таким образом, на последнем месте (номер n-1) в массиве окажется наибольшее значение. Например,
цепочка преобразований для массива 8 10 2 4 8 10 2 4 8 2 10 4
8 2 4 10. Далее просматриваем все пары элементов с первого, но до элемента с номером n-2. Тогда на предпоследнем месте окажется второе по величине значение. Аналогично продолжаем процесс. Если при очередном просмотре не было произведено ни одного обмена, значит, сортировку можно завершать досрочно (команда break).
Если значения элементов уподобить размерам пузырьков, то процесс сортировки похож на то, как самые большие пузырьки по очереди всплывают, оттесняя остальных.
// Реализация алгоритма сортировки. #include <iostream>
using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n); void bubble_sort(int a[n_max],int n);
int main(){ int a[n_max];
52
int n; input_v(a,n); output_v(a,n); bubble_sort(a,n); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n){
for (int i=0;i<=n/2;i++) swap(a[i],a[n-1-i]);
}
void bubble_sort(int a[n_max],int n)
{
int tmp,j; bool flag;
for (int i=0; i<n; i++)
{
flag=true;
j=0;
while (j<n-i-1)
{
if (a[j]>a[j+1])
{
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
flag=false;
53
}
j++;
}
if (flag) break;
}
}
Пример 5. Выполнить сортировку выбором целочисленного мас-
сива A(n).
Пояснения. Для реализации алгоритма сортирови выбором среди чисел a[0], a[1], ..., a[n-1] находим наименьший элемент и меняем его местами с элементом a[0]. Далее рассматриваем числа a[1], ..., a[n-1], то есть все, кроме первого элемента, и наименьший среди них меняем с числом a[1]. Далее продолжаем процесс аналогичным образом.
Сложность сортировки: при больших n работает слишком медленно, на практике применяют крайне редко (как и сортировка пузырьком). Хотя простота и скорость написания такого кода иногда может оказаться существенным преимуществом.
#include <iostream> using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n); void select_sort(int a[n_max],int n);
int main(){ int a[n_max]; int n; input_v(a,n); output_v(a,n);
select_sort(a,n); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
54
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n){
for (int i=0;i<=n/2;i++) swap(a[i],a[n-1-i]);
}
void select_sort(int a[n_max],int n){ int imin, tmp;
for (int i=0; i<n-1; i++)
{
imin=i;
for (int j=i+1; j<n; j++) if (a[j]<a[imin]) imin=j;
if (imin>i)
{
tmp=a[imin];
a[imin]=a[i];
a[i]=tmp;
}
}
}
Пример 6. Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) влево на одну позицию
/* Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) влево на одну позицию*/
#include <iostream> using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n); void preobraz(int a[n_max],int n);
int main(){
55
int a[n_max]; int n; input_v(a,n); output_v(a,n); preobraz(a,n); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n){ int c=a[0];
for (int i=0;i<n-1;i++) a[i]=a[i+1];
a[n-1]=c;
}
Пример 7. Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) влево на k позиций.
/* Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) влево на k позиций*/
#include <iostream> using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n);
void preobraz(int a[n_max],int n,int k);
int main(){
56
int a[n_max]; int n,k; input_v(a,n); output_v(a,n); cout<<endl;
cout<<"enter k= "; cin>>k; preobraz(a,n,k); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n,int k){
for(int j=1;j<=k;j++){ int c=a[0];
for (int i=0;i<n-1;i++) a[i]=a[i+1];
a[n-1]=c;
}
}
Пример 8. Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) вправо на одну позицию
/* Выполнить циклический сдвиг элементов исходного целочисленного массива A(N) вправо на одну позицию*/
#include <iostream> using namespace std;
57
const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n); void preobraz(int a[n_max],int n);
int main(){ int a[n_max]; int n; input_v(a,n); output_v(a,n); cout<<endl; preobraz(a,n); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void preobraz(int a[n_max],int n){
int c=a[n-1];
for (int i=n-1;i>0;i--) a[i]=a[i-1];
a[0]=c;
}
Пример 9. Удалить k-й элемент заданного целочисленного массива
/* Удалить k-й элемент заданного целочисленного массива */
#include <iostream>
58
using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n);
void udalenie(int a[n_max],int n,int k);
int main(){ int a[n_max]; int n,k; input_v(a,n); output_v(a,n); cout<<endl; cout<<"k="; cin>>k;
udalenie(a,n,k); n--; cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void udalenie(int a[n_max],int n,int k){
for (int i=k-1;i<n-1;i++) a[i]=a[i+1];
}
59
Пример 10. Удалить все отрицательные элементы заданного целочисленного массива
/* Удалить все отрицательные элементы заданного целочисленного массива */
#include <iostream> using namespace std; const int n_max=30;
void input_v(int a[n_max],int &n); void output_v(int a[n_max],int n); void udalenie(int a[n_max],int &n);
int main(){ int a[n_max]; int n; input_v(a,n); output_v(a,n); cout<<endl; udalenie(a,n); cout<<endl; output_v(a,n); return 0;
}
void input_v(int a[n_max],int &n){ cout<<"n=";cin>>n;
for (int i=0;i<n;i++){ cout<<"a["<<i+1<<"]= "; cin>>a[i];
}
}
void output_v(int a[n_max],int n){ for (int i=0;i<n;i++) cout<<a[i]<<"\t";
}
void udalenie(int a[n_max],int &n){
for(int j=n-1;j>=0;j--) if (a[j]<0){
for (int i=j;i<n-1;i++) a[i]=a[i+1];
n--;
}
}
60
