Задача флага Нидерландов — различия между версиями
Oxygen3 (обсуждение | вклад) (Новая страница: «'''Задача флага Нидерландов''' (англ. ''Dutch national flag problem, DNF''). Флаг Нидерландов состоит из тре...») |
м (rollbackEdits.php mass rollback) |
||
(не показано 7 промежуточных версий 3 участников) | |||
Строка 1: | Строка 1: | ||
− | + | Флаг Нидерландов состоит из трех цветов: красного, белого и синего. Получая шары этих трех цветов, расположенных в случайном порядке, задача состоит в том, чтобы организовать их таким образом, что все шары одного цвета были вместе, а и их общие цвета шли в порядке как на данном флаге. | |
==Сортировка набора, состоящего из 0 и 1== | ==Сортировка набора, состоящего из 0 и 1== | ||
{{Задача | {{Задача | ||
|definition = | |definition = | ||
− | Дан массив <tex>a[ | + | Дан массив <tex>a[0..n-1]</tex> из <tex>n</tex> чисел <tex>0</tex> и <tex>1</tex>. Требуется разделить элементы друг от друга так, чтобы сначала оказались все <tex>0</tex>, а в конце <tex>1</tex>. |
}} | }} | ||
===Пример=== | ===Пример=== | ||
− | <tex> [0, 1, 0, 1, 0, 0, 1, 1, 1, 0] </tex><br> | + | Исходный массив: <tex> a = [0, 1, 0, 1, 0, 0, 1, 1, 1, 0]</tex> <br> |
− | <tex> [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] </tex> | + | Полученный массив: <tex> sort(a) = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] </tex> |
+ | |||
===Алгоритм=== | ===Алгоритм=== | ||
− | Будем поддерживать два указателя. Инициализируем первый индекс <tex>left = | + | Будем поддерживать два указателя. Инициализируем первый индекс <tex>left = 0</tex> и второй индекс <tex>right = n - 1</tex>. |
У будем делать следующее пока <tex>left < right</tex> | У будем делать следующее пока <tex>left < right</tex> | ||
Строка 16: | Строка 17: | ||
# Уменьшаем <tex>right</tex> на <tex>1</tex> пока не <tex>a[right] = 1</tex>. | # Уменьшаем <tex>right</tex> на <tex>1</tex> пока не <tex>a[right] = 1</tex>. | ||
# Если <tex>left < right</tex>, то меняем местами <tex>a[left]</tex> и <tex>a[right]</tex>, <tex>left\texttt{++}</tex>, <tex>right\texttt{--}</tex>. | # Если <tex>left < right</tex>, то меняем местами <tex>a[left]</tex> и <tex>a[right]</tex>, <tex>left\texttt{++}</tex>, <tex>right\texttt{--}</tex>. | ||
+ | |||
===Псевдокод=== | ===Псевдокод=== | ||
− | sort('''int''' | + | '''int'''[] sort('''int'''[] a): |
− | '''int''' left = | + | '''int''' left = 0, right = n - 1 |
'''while''' (left < right) | '''while''' (left < right) | ||
'''while''' (arr[left] == 0 '''and''' left < right) | '''while''' (arr[left] == 0 '''and''' left < right) | ||
Строка 33: | Строка 35: | ||
{{Задача | {{Задача | ||
|definition = | |definition = | ||
− | Дан массив <tex>a[ | + | Дан массив <tex>a[0..n-1]</tex> из <tex>n</tex> чисел <tex>0</tex>, <tex>1</tex> и <tex>2</tex>. Требуется разделить их друг от друга так, чтобы сначала шли все <tex>0</tex>, потом все <tex>1</tex> и все <tex>2</tex> в конце. |
}} | }} | ||
===Пример=== | ===Пример=== | ||
− | <tex> [0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1] </tex><br> | + | Исходный массив: <tex> a = [0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1]</tex><br> |
− | <tex> [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] </tex> | + | Полученный массив: <tex> sort(a) = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2] </tex> |
+ | |||
===Алгоритм=== | ===Алгоритм=== | ||
− | Будем поддерживать три указателя. Инициализация: <tex>lo = | + | Будем поддерживать три указателя. Инициализация: <tex>lo = 0; mid = 0; hi = n - 1</tex>. |
У будем делать следующее пока <tex>mid \leqslant right</tex> | У будем делать следующее пока <tex>mid \leqslant right</tex> | ||
Строка 47: | Строка 50: | ||
Инвариант работы алгоритма: | Инвариант работы алгоритма: | ||
− | # <tex>a[ | + | # <tex>a[0..lo-2] = 0</tex> |
− | # <tex>a[lo..mid- | + | # <tex>a[lo-1..mid-2] = 1</tex> |
− | # <tex>a[mid..hi]</tex> неизвестны | + | # <tex>a[mid-1..hi-1]</tex> неизвестны |
− | # <tex>a[hi | + | # <tex>a[hi..n-1] = 2</tex> |
+ | |||
===Псевдокод=== | ===Псевдокод=== | ||
− | sort('''int''' | + | '''int'''[] sort('''int'''[] a) |
− | '''int''' lo = | + | '''int''' lo = 0, mid = 0, hi = n - 1 |
'''while''' mid <tex>\leqslant</tex> right | '''while''' mid <tex>\leqslant</tex> right | ||
'''switch''' (a[mid]) | '''switch''' (a[mid]) | ||
− | + | '''case''' 0: | |
− | + | swap(a[lo++], a[mid++]) | |
− | + | '''break''' | |
− | + | '''case''' 1: | |
− | + | mid++ | |
− | + | '''break''' | |
− | + | '''case''' 2: | |
− | + | swap(a[mid], a[hi--]) | |
− | + | '''break''' | |
'''return''' a | '''return''' a | ||
== См. также == | == См. также == |
Текущая версия на 19:05, 4 сентября 2022
Флаг Нидерландов состоит из трех цветов: красного, белого и синего. Получая шары этих трех цветов, расположенных в случайном порядке, задача состоит в том, чтобы организовать их таким образом, что все шары одного цвета были вместе, а и их общие цвета шли в порядке как на данном флаге.
Содержание
Сортировка набора, состоящего из 0 и 1
Задача: |
Дан массив | из чисел и . Требуется разделить элементы друг от друга так, чтобы сначала оказались все , а в конце .
Пример
Исходный массив:
Полученный массив:
Алгоритм
Будем поддерживать два указателя. Инициализируем первый индекс
и второй индекс .У будем делать следующее пока
- Увеличиваем на пока не .
- Уменьшаем на пока не .
- Если , то меняем местами и , , .
Псевдокод
int[] sort(int[] a): int left = 0, right = n - 1 while (left < right) while (arr[left] == 0 and left < right) left++ while (arr[right] == 1 and left < right) right-- if (left < right) swap(a[left], a[right]) left++ right-- return a
Сортировка набора, состоящего из 0, 1 и 2
Задача: |
Дан массив | из чисел , и . Требуется разделить их друг от друга так, чтобы сначала шли все , потом все и все в конце.
Пример
Исходный массив:
Полученный массив:
Алгоритм
Будем поддерживать три указателя. Инициализация:
.У будем делать следующее пока
- Если , то меняем местами и , , .
- Если , то .
- Если , то меняем местами и , .
Инвариант работы алгоритма:
- неизвестны
Псевдокод
int[] sort(int[] a)
int lo = 0, mid = 0, hi = n - 1
while mid
right
switch (a[mid])
case 0:
swap(a[lo++], a[mid++])
break
case 1:
mid++
break
case 2:
swap(a[mid], a[hi--])
break
return a