Сортировка методом пузырька в python

Bubble sort program in C language using function

#include <stdio.h>

void bubble_sort(long , long);

int main(){  long array100, n, c;

  printf(«Enter number of elements\n»);  scanf(«%ld», &n);

  printf(«Enter %ld integers\n», n);

  for (c = ; c < n; c++)    scanf(«%ld», &arrayc);

  bubble_sort(array, n);

  printf(«Sorted list in ascending order:\n»);

  for (c = ; c < n; c++)     printf(«%ld\n», arrayc);

  return ;}

void bubble_sort(long list, long n){  long c, d, t;

  for (c = ; c < n — 1; c++) {    for (d = ; d < n — c — 1; d++) {      if (listd > listd+1) {        /* Swapping */        t         = listd;        listd   = listd+1;        listd+1 = t;      }    }  }}

We can use the Bubble Sort algorithm to check if an array is sorted or not. If no swapping takes place, then the array is sorted. We can improve its best-case complexity to O(n).

#include <stdio.h>

int is_Array_Sorted(int , int);

int main(){  int a100, n, c;

  printf(«Enter number of elements\n»);  scanf(«%d», &n);

  printf(«Enter %d integers\n», n);

  for (c = ; c < n; c++)    scanf(«%d», &ac);

  if (is_Array_Sorted(a, n))    printf(«The array is sorted.\n»);  else    printf(«The array isn’t sorted.\n»);

  return ;}

int is_Array_Sorted(int a, int n) {  int c, d, sorted = 1, t;

  for (c = ; c < n — 1; c++) {    for (d = ; d < n — c — 1; d++) {      if (ad > ad+1) {        t = ad;        ad = ad+1;        ad+1 = t;        return ;      }    }  }  return 1;}

Оптимизация[править]

  • Можно заметить, что после -ой итерации внешнего цикла последних элементов уже находятся на своих местах в отсортированном порядке, поэтому нет необходимости производить их сравнения друг с другом. Следовательно, внутренний цикл можно выполнять не до , а до .
  • Также заметим, что если после выполнения внутреннего цикла не произошло ни одного обмена, то массив уже отсортирован, и продолжать что-то делать бессмысленно. Поэтому внутренний цикл можно выполнять не раз, а до тех пор, пока во внутреннем цикле происходят обмены.

При использовании первой оптимизации сортировка принимает следующий вид:

function bubbleSort(a):
  for i = 0 to n - 2
    for j = 0 to n - i - 2
      if a > a
        swap(a, a)

При использовании же обеих оптимизаций сортировка пузырьком выглядит так:

function bubbleSort(a):
  i = 0
  t = true
  while t
    t = false
    for j = 0 to n - i - 2
      if a > a
        swap(a, a)
        t = true
    i = i + 1

Пример сортировки пузыря

Учитывая последовательность: 12, 16, 11, 10, 14, 13 Количество элементов ( n ): 6 Давайте начнем-

Шаг 1: Переменные Я и J Представление отсортированных элементов и позиции.
Шаг 2: N 6. N.

Шаг 3: Установить Я Как 0. я

Шаг 4: Установить J Как 1. j

Шаг 5: Сравнение позиций J и J + 1 Элемент в положении 1 (12) не превышает один при 2 (16).
Шаг 6: Увеличение J Отказ j

Шаг 7: J (2) не N-I (6), поэтому мы идем к шагу 5.
Шаг 5: Положение 2 (16) больше, чем позиция 3 (11), поэтому мы поменяем.
Последовательность: 12, 11 , 16 , 10, 14, 13

Шаг 6: Увеличение J Отказ j

Шаг 7: 3 не 6, поэтому мы идем к шагу 5.
Шаг 5: 16 больше 10, поэтому мы поменяем. Последовательность: 12, 11, 10 , 16 , 14, 13

Шаг 6: Увеличение J Отказ j

Шаг 7: 4 не 6, поэтому мы идем к шагу 5.
Шаг 5: 16 больше 14, поэтому мы поменяем. Последовательность: 12, 11, 10, 14 , 16 13.

Шаг 6: Увеличение J Отказ j

Шаг 7: 5 не 6, поэтому мы идем к шагу 5.
Шаг 5: 16 больше 13, поэтому мы поменяем. Последовательность: 12, 11, 10, 14, 13 , 16.

Шаг 6: Увеличение J Отказ j

Шаг 7: J (6) равен N-I (6), поэтому мы переходим к шагу 8

Обратите внимание, что наибольший элемент (16) находится в конце, и мы отсортировали один элемент наверняка. Шаг 8: Увеличение я

я

Шаг 9: Я (1) не N-1 (5), поэтому мы повторяем все это по сравнению с шагом 4, а цикл продолжается, полученные изменения в последовательности будут выглядеть так:

11 , 12 , 10, 14, 13, 16 11, 10 , 12 , 14, 13, 16 11, 10, 12 , 14 , 13, 16 11, 10, 12, 13 , 14 , 16 10 , 11 12, 13, 14 , 16 10, 11 , 12 , 13, 14 , 16 10, 11, 12 , 13 , 14 , 16 10 , 11 12, 13 , 14 , 16 10, 11 , 12 , 13 , 14 , 16 10 , 11 , 12 , 13 , 14 , 16 10 , 11 , 12 , 13 , 14 , 16.

После этого Я становится 5, что это N-1 Таким образом, контурные контуры и алгоритм говорит нам, что список отсортирован. Также кажется, что список может быть отсортирован до окончания алгоритма, что просто означает, что заданная последовательность была несколько отсортирована до того, как она была передана алгоритму.

Объяснение:

функция shell_sort ():

  • Эта функция принимает список и его размер в качестве параметров
  • Интервал ‘h’ is инициализируется до половины размера списка
  • Теперь выполните следующие действия, пока значение h не станет меньше нуляПовторите список от h до конца, Храните каждый элемент во временной переменнойСравните элементы, находящиеся на интервале h, и при необходимости поменяйте местами
  • Повторите форму списка h до конца
  • Храните каждый элемент во временной переменной
  • Сравните элементы, находящиеся на интервале h, и при необходимости поменяйте местами

Наконец, значение h обновляется, и процесс продолжается до тех пор, пока список не будет полностью отсортирован

Модификации[править]

Сортировка чет-нечетправить

Сортировка чет-нечет (англ. odd-even sort) — модификация пузырьковой сортировки, основанная на сравнении элементов стоящих на четных и нечетных позициях независимо друг от друга. Сложность — .
Псевдокод указан ниже:

function oddEvenSort(a):
  for i = 0 to n - 1 
    if i mod 2 == 0
      for j = 2 to n - 1 step 2
        if a < a
          swap(a, a)  
    else      
      for j = 1 to n - 1 step 2
        if a < a
          swap(a, a)

Преимущество этой сортировки — на нескольких процессорах она выполняется быстрее, так как четные и нечетные индексы сортируются параллельно.

Сортировка расческойправить

Сортировка расческой (англ. comb sort) — модификация пузырьковой сортировки, основанной на сравнении элементов на расстоянии. Сложность — , но стремится к . Является самой быстрой квадратичной сортировкой. Недостаток — она неустойчива. Псевдокод указан ниже:

function combSort(a):
  k = 1.3
  jump = n
  bool swapped = true
  while jump > 1 and swapped
    if jump > 1
      jump /= k
    swapped = false
    for i = 0 to size - jump - 1
      if a < a
        swap(a, a)
        swapped = true

Пояснения: Изначально расстояние между сравниваемыми элементами равно , где — оптимальное число для этого алгоритма. Сортируем массив по этому расстоянию, потом уменьшаем его по этому же правилу. Когда расстояние между сравниваемыми элементами достигает единицы, массив досортировывается обычным пузырьком.

Сортировка перемешиваниемправить

Сортировка перемешиванием (англ. cocktail sort), также известная как Шейкерная сортировка — разновидность пузырьковой сортировки, сортирующая массив в двух направлениях на каждой итерации. В среднем, сортировка перемешиванием работает в два раза быстрее пузырька. Сложность — , но стремится она к , где — максимальное расстояние элемента в неотсортированном массиве от его позиции в отсортированном массиве. Псевдокод указан ниже:

function shakerSort(a):
  begin = -1
  end = n - 2
  while swapped
    swapped = false   
    begin++
    for i = begin to end 
      if a > a 
        swap(a, a)
        swapped = true    
    if !swapped
      break    
    swapped = false 
    end--
    for i = end downto begin
      if a > a 
        swap(a, a)
        swapped = true

Что такое пузырьковая сортировка

Bubble sort — это алгоритм сортировки, который сортирует элементы в порядке возрастания. Он многократно сравнивает соседние элементы. И, если элемент слева больше, чем элемент справа, элементы меняются местами.

Пример таков.

5  8  1  6  9  2

Рассмотрим 5 и 8. Нет необходимости менять два числа на 5 1; вместо этого мы меняем два элемента. Теперь список выглядит следующим образом.

5 1 8  6  9  2

Теперь рассмотрим 8 и 6. Поскольку 8> 6, мы меняем эти два числа. Список выглядит следующим образом.

5  1  6  8  9  2

Теперь рассмотрим 8 и 9. Нет необходимости менять числа как 8 <9. Затем рассмотрим 9 и 2. Мы должны поменять местами два значения как 9> 2. После завершения первой итерации список выглядит, как показано ниже.

5  1   6  8  2  9

Самый большой предмет находится в самой правой позиции. Теперь нам нужно рассмотреть только 5 1 6 9 2. Мы можем сравнить 5 и 1. При 5> 1 мы меняем значения. Тогда, как и прежде, мы можем следовать той же процедуре. Список после завершения итерации выглядит следующим образом.

1  5  6  2  8  9

Сейчас 8 и 9 — самые большие элементы в списке, но они уже отсортированы. Теперь мы должны рассмотреть 1 5 6 2. Этот процесс продолжается и, наконец, мы можем получить отсортированный список.

Алгоритм

Алгоритм состоит из повторяющихся проходов по сортируемому массиву. За каждый проход элементы последовательно сравниваются попарно и, если порядок в паре неверный, выполняется обмен элементов. Проходы по массиву повторяются N−1{\displaystyle N-1} раз или до тех пор, пока на очередном проходе не окажется, что обмены больше не нужны, что означает — массив отсортирован. При каждом проходе алгоритма по внутреннему циклу, очередной наибольший элемент массива ставится на своё место в конце массива рядом с предыдущим «наибольшим элементом», а наименьший элемент перемещается на одну позицию к началу массива («всплывает» до нужной позиции, как пузырёк в воде. Отсюда и название алгоритма).

Как работает Быстрая сортировка

Быстрая сортировка чаще всего не сможет разделить массив на равные части. Это потому, что весь процесс зависит от того, как мы выбираем опорный элемент. Нам нужно выбрать опору так, чтобы она была примерно больше половины элементов и, следовательно, примерно меньше, чем другая половина элементов. Каким бы интуитивным ни казался этот процесс, это очень сложно сделать.

Подумайте об этом на мгновение — как бы вы выбрали адекватную опору для вашего массива? В истории быстрой сортировки было представлено много идей о том, как выбрать центральную точку — случайный выбор элемента, который не работает из-за того, что «дорогой» выбор случайного элемента не гарантирует хорошего выбора центральной точки; выбор элемента из середины; выбор медианы первого, среднего и последнего элемента; и еще более сложные рекурсивные формулы.

Самый простой подход — просто выбрать первый (или последний) элемент. По иронии судьбы, это приводит к быстрой сортировке на уже отсортированных (или почти отсортированных) массивах.

Именно так большинство людей выбирают реализацию быстрой сортировки, и, так как это просто и этот способ выбора опоры является очень эффективной операцией, и это именно то, что мы будем делать.

Теперь, когда мы выбрали опорный элемент — что нам с ним делать? Опять же, есть несколько способов сделать само разбиение. У нас будет «указатель» на нашу опору, указатель на «меньшие» элементы и указатель на «более крупные» элементы.

Цель состоит в том, чтобы переместить элементы так, чтобы все элементы, меньшие, чем опора, находились слева от него, а все более крупные элементы были справа от него. Меньшие и большие элементы не обязательно будут отсортированы, мы просто хотим, чтобы они находились на правильной стороне оси. Затем мы рекурсивно проходим левую и правую сторону оси.

Рассмотрим пошагово то, что мы планируем сделать, это поможет проиллюстрировать весь процесс. Пусть у нас будет следующий список.

29 | 99 (low),27,41,66,28,44,78,87,19,31,76,58,88,83,97,12,21,44 (high)

Выберем первый элемент как опору 29), а указатель на меньшие элементы (называемый «low») будет следующим элементом, указатель на более крупные элементы (называемый «high») станем последний элемент в списке.

29 | 99 (low),27,41,66,28,44,78,87,19,31,76,58,88,83,97,12,21 (high),44

Мы двигаемся в сторону high то есть влево, пока не найдем значение, которое ниже нашего опорного элемента.

29 | 99 (low),27,41,66,28,44,78,87,19,31,76,58,88,83,97,12,21 (high),44

  • Теперь, когда наш элемент high указывает на элемент 21, то есть на значение меньше чем опорное значение, мы хотим найти значение в начале массива, с которым мы можем поменять его местами. Нет смысла менять местами значение, которое меньше, чем опорное значение, поэтому, если low указывает на меньший элемент, мы пытаемся найти тот, который будет больше.
  • Мы перемещаем переменную low вправо, пока не найдем элемент больше, чем опорное значение. К счастью, low уже имеет значение 89.
  • Мы меняем местами low и high:

29 | 21 (low),27,41,66,28,44,78,87,19,31,76,58,88,83,97,12,99 (high),44

  • Сразу после этого мы перемещает high влево и low вправо (поскольку 21 и 89 теперь на своих местах)
  • Опять же, мы двигаемся high влево, пока не достигнем значения, меньшего, чем опорное значение, и мы сразу находим — 12
  • Теперь мы ищем значение больше, чем опорное значение, двигая low вправо, и находим такое значение 41

Этот процесс продолжается до тех пор, пока указатели low и high наконец не встретятся в одном элементе:

29 | 21,27,12,19,28 (low/high),44,78,87,66,31,76,58,88,83,97,41,99,44

Мы больше не используем это опорное значение, поэтому остается только поменять опорную точку и high, и мы закончили с этим рекурсивным шагом:

28,21,27,12,19,29,44,78,87,66,31,76,58,88,83,97,41,99,44

Как видите, мы достигли того, что все значения, меньшие 29, теперь слева от 29, а все значения больше 29 справа.

Затем алгоритм делает то же самое для коллекции 28,21,27,12,19 (левая сторона) и 44,78,87,66,31,76,58,88,83,97,41,99,44 (правая сторона). И так далее.

Implementing Bubble Sort Algorithm

Following are the steps involved in bubble sort(for sorting a given array in ascending order):

  1. Starting with the first element(index = 0), compare the current element with the next element of the array.
  2. If the current element is greater than the next element of the array, swap them.
  3. If the current element is less than the next element, move to the next element. Repeat Step 1.

Let’s consider an array with values

Below, we have a pictorial representation of how bubble sort will sort the given array.

So as we can see in the representation above, after the first iteration, is placed at the last index, which is the correct position for it.

Similarly after the second iteration, will be at the second last index, and so on.

Time to write the code for bubble sort:

Although the above logic will sort an unsorted array, still the above algorithm is not efficient because as per the above logic, the outer loop will keep on executing for 6 iterations even if the array gets sorted after the second iteration.

So, we can clearly optimize our algorithm.

Выполняет сортировку последовательности по возростанию/убыванию.

Параметры:

  • — объект, поддерживающий итерирование
  • — пользовательская функция, которая применяется к каждому элементу последовательности
  • — порядок сортировки

Описание:

Функция вернет новый отсортированный t-list] из итерируемых элементов. Функция имеет два необязательных аргумента, которые должны быть указаны в качестве аргументов ключевых слов.

Аргумент принимает функцию, например . Переданная функция вычисляет результат для каждого элемента последовательности, который используется для сравнения элементов при сортировке. Значением по умолчанию является , т.е. сравнивать элементы напрямую (как есть).

Аргумент имеет логическое значение. Если установлено значение , то элементы списка сортируются в обратной последовательности (по убыванию).

Используйте для преобразования функции, использующей cmp (старый стиль) в использующую key (новый стиль).

Встроенная функция sorted() является гарантированно стабильной. Это означает, что когда несколько элементов последовательности имеют равные значения, их первоначальный порядок сохраняется. Такое поведение полезно при сортировке в несколько проходов.

Примеры различных способов сортировки последовательностей.

Сортировка слов в предложении без учета регистра:

line = 'This is a test string from Andrew'
x = sorted(line.split(), key=str.lower)
print(x)
# 

Сортировка сложных объектов с использованием индексов в качестве ключей :

student = 
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
    

# Сортируем по возрасту student
x = sorted(student, key=lambda student student2])
print(x)
# 

Тот же метод работает для объектов с именованными атрибутами.

class Student
    def __init__(self, name, grade, age):
        self.name = name
        self.grade = grade
        self.age = age
    def __repr__(self):
        return repr((self.name, self.grade, self.age))

student = 
    Student('john', 'A', 15),
    Student('jane', 'B', 12),
    Student('dave', 'B', 10),
    

x = sorted(student, key=lambda student student.age)
print(x)
# 

Сортировка по убыванию:

student = 
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
    

# Сортируем по убыванию возраста student
x = sorted(student, key=lambda i i2], reverse=True)
print(x)
# 

Стабильность сортировки и сложные сортировки:

data = 
x = sorted(data, key=lambda data data])
print(x)
# 

Обратите внимание, как две записи (‘blue’, 1), (‘blue’, 2) для синего цвета сохраняют свой первоначальный порядок. Это замечательное свойство позволяет создавать сложные сортировки за несколько проходов по нескольким ключам

Например, чтобы отсортировать данные учащиеся по возрастанию успеваемости, а затем по убыванию возраста. Успеваемость будет первым ключом, возраст вторым

Это замечательное свойство позволяет создавать сложные сортировки за несколько проходов по нескольким ключам. Например, чтобы отсортировать данные учащиеся по возрастанию успеваемости, а затем по убыванию возраста. Успеваемость будет первым ключом, возраст вторым.

student = 
    ('john', 15, 4.1),
    ('jane', 12, 4.9),
    ('dave', 10, 3.9),
    ('kate', 11, 4.1),
    

# По средней оценке
x = sorted(student, key=lambda num num2])
# По убыванию возраста
y = sorted(x, key=lambda age age1], reverse=True)
print(y)
# 

А еще, для сортировок по нескольким ключам, удобнее использовать модуль . Функции модуля допускают несколько уровней сортировки. Например, как в предыдущем примере успеваемость будет первым ключом, возраст вторым.Только сортировать будем все по возрастанию:

from operator import itemgetter

x = sorted(student, key=itemgetter(2,1))
print(x)
# 

Description

We can imagine that sorted numbers are bubbles, the ones with lower value are lighter than the ones with higher value, hence they ascend to the surface faster.

Bubble sort advances similarly. In every step it compares two adjacent elements and if the lower value is on the left side of the higher, bubble sort swaps them (lighter value ascends to the end of the array) and with the same logic algorithm proceeds to the next item.

After one iteration the lowest value is located at the end of the array. Algorithm now repeats the procedure with reduced array (the last element is already sorted). After iterations is the array completely sorted, because the last bubble is sorted trivially.

Важность сортировки алгоритмов

Что такое сортировка? И почему это так важно? Это вопросы, которые мы постараемся ответить в этом разделе. Из книг в библиотеке и словах в словаре к записям базы данных и инструкции в процессоре мы испытали сортировку много раз

Из книг в библиотеке и словах в словаре к записям базы данных и инструкции в процессоре мы испытали сортировку много раз.

« в информатике, сортировка – это акт организации вещей в упорядоченной последовательности ». – Википедия

Это означает, что когда мы сортируем вещи, нам нужно знать критерии, на которые мы будем организовать последовательность, переданную нам. Для целей настоящего Учебника мы будем предполагать, что критерии – это значение числа, и мы сортируем заданную последовательность чисел.

В информатике наиболее важной целью сортировки состоит в том, чтобы произвести эффективные алгоритмы. Двоичный поиск – исключительно быстрый алгоритм поиска, который не будет возможно в несортированной коллекции объектов

Почти все установленные операции работают очень быстро на сортировке данных.

Помимо эффективных алгоритмов, сортировка используется, когда очень требование программы сортируется что-то, как программа, которая работает с палубой карт. Следовательно, алгоритмы сортировки являются одним из самых фундаментальных концепций, который должен знать программист.

Пример работы алгоритма[править]

Возьмём массив и отсортируем значения по возрастанию, используя сортировку пузырьком. Выделены те элементы, которые сравниваются на данном этапе.

Первый проход:

До После Описание шага
5 1 4 2 8 1 5 4 2 8 Здесь алгоритм сравнивает два первых элемента и меняет их местами.
1 5 4 2 8 1 4 5 2 8 Меняет местами, так как 5 > 4
1 4 5 2 8 1 4 2 5 8 Меняет местами, так как 5 > 2
1 4 2 5 8 1 4 2 5 8 Теперь, ввиду того, что элементы стоят на своих местах (8 > 5), алгоритм не меняет их местами.

Второй проход:

До После Описание шага
1 4 2 5 8 1 4 2 5 8
1 4 2 5 8 1 2 4 5 8 Меняет местами, так как 4 > 2
1 2 4 5 8 1 2 4 5 8
1 2 4 5 8 1 2 4 5 8

Теперь массив полностью отсортирован, но неоптимизированный алгоритм проведет еще два прохода, на которых ничего не изменится, в отличие от алгоритма, использующего вторую оптимизацию, который сделает один проход и прекратит свою работу, так как не сделает за этот проход ни одного обмена.

Идея алгоритма

Соседние элементы последовательности сравниваются между собой и, в случае необходимости, меняются местами. В качестве примера рассмотрим упорядочивание методом пузырьковой сортировки массива, количество элементов n которого равно 5: 8, 2, 4, 7, 5. В итоге должен получиться массив с элементами, располагающимися в порядке возрастания их значений.Вначале сравниваются два первых элемента последовательности: 8 и 2, так как значение первого элемента больше значения второго, т. е. 8>2, они меняются местами. Далее, сравниваются второй и третий элементы: девятка больше четверки, следовательно, элементы снова обмениваются позициями. Аналогично алгоритм продолжает выполняться до тех пор, пока все элементы массива не окажутся на своих местах. Всего для этого потребуется n*(n-1) сравнений. В частности, на данной последовательности произведено 20 сравнений и только 5 перестановок.
.

Разница между пузырьковой сортировкой и выборочной сортировкой

Определение

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

функциональность

Пузырьковая сортировка сравнивает соседние элементы и соответственно меняет местами, в то время как сортировка выбора выбирает минимальный элемент из несортированного подмассива и помещает его в следующую позицию отсортированного подмассива.

КПД

Кроме того, еще одно различие между сортировкой пузырьков и сортировкой выбора заключается в том, что сортировка выбора эффективна по сравнению с сортировкой пузырьков.

скорость

Кроме того, скорость является еще одной разницей между сортировкой пузырьков и сортировкой выбора. Сортировка выбора происходит быстрее по сравнению с пузырьковой сортировкой.

метод

Кроме того, еще одно различие между пузырьковой сортировкой и сортировкой выбора заключается в том, что в пузырьковой сортировке используется обмен элементов, а в выборочной сортировке используется выбор элементов.

Заключение

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

Заключение

В этом уроке мы изучали, что такое сортировка и где он используется, то мы узнали, как Bubble Sort работает, мы придумали алгоритм и реализовали пузырь в Python.

Bubble Sort – один из многих сортировковных алгоритмов, и он далеко от лучшего, но это очень легко реализовать. Причина, по которой она не используется слишком часто, так это то, что у него сложность O (n 2 ), что означает, что количество элементов в списке удвоилось, время, необходимое для сортировки их использования этого алгоритма, увеличится в четыре раза.

Таким образом, для очень большого количества данных этот алгоритм становится неэффективным. Тем не менее, зная пузырь, как программист важен, и я надеюсь, что вы узнали что-то.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector