Известные отношения классов:
Также известно, что если \(\mathrm{P} = \mathrm{NP}\), то \(\mathrm{EXPTIME} = \mathrm{NEXPTIME}\).
Вопрос равенства P и NP – один из главных нерешенных вопросов современной информатики.
\(23\times 43\)
43 | 23 |
86 | 11 |
172 | 5 |
344 | 2 |
688 | 1 |
Имеется массив \(a\) размера \(n\) (индексация с 1), требуется найти элемент массива равный \(P\).
Имеется массив \(a\) размера \(n\) (индексация с 1), требуется найти минимальный элемент.
Если массив упорядочен, линейный поиск неэффективен
Сложность алгоритма \(O(\log n)\)
Общая постановка: упорядочить произвольный массив \(n\) элементов по возрастанию (точнее, неубыванию). Полагается, что для элементов корректно определены операции \(<\), \(>\) и \(=\).
Идея:
for m from n-1 to 1
for j from 1 to m
if a[j] > a[j+1]
swap(a[j], a[j+1])
end if
end for j
end for m
Оптимизация: раннее завершение если массив не отсортирован
for m from n-1 to 1
swapped = false
for j from 1 to m
if a[j] > a[j+1]
swapped = true
swap(a[j], a[j+1])
end if
end for j
if swapped
break
end if
end for m
for i from 1 to n - 1
min := i
for j from i + 1 to n
if a[j] < a[min]
min := j
end if
end for j
if indexMin ≠ i
swap(a[min], a[i])
end if
end for i
Сложность: \(n(n-1)/2 = O(n^2)\) операций сравнения. Не более \(n-1 = O(n)\) обменов.
for i from 2 to n
x := a[i]
j := i
while (j > 1 and a[j-1] > x)
a[j] := a[j-1]
j := j - 1
end while
a[j] := x
end for i
algorithm merge_sort(a[n])
if n ≤ 1
return a
mid := n/2
left := merge_sort(a[1..mid])
right := merge_sort(a[mid+1..n])
return merge(left, right)
end algorithm merge_sort
algorithm merge(a[n], b[m])
result := new array[n+m]
i := 1
j := 1
k := 1
while (i ≤ n and j ≤ m)
if a[i] < b[j]
result[k] := a[i]
i := i+1
else
result[k] := b[j]
j := j+1
end if
k := k+1
end while
while (i ≤ n)
result[k] := a[i]
k := k+1
i := i+1
end while
while (j ≤ m)
result[k] := b[j]
k := k+1
j := j+1
end while
return result
end algorithm merge
Тогда:
\(t(n) = 2t(n/2)+c\cdot n\)
\(t(n) = 2(2t(n/2^2)+c\cdot n/2)+c\cdot n\)
\(t(n) = 2^2 t(n/2^2)+2c\cdot n\)
\(t(n) = 2^2 (2t(n/2^3)+c\cdot n/4)+2c\cdot n\)
\(t(n) = 2^3t(n/2^3)+3c\cdot n\)
\(\ldots\)
\(t(n) = c 2^{\log_2 n} + c\cdot n \log_2 n\)
\(t(n) = c n + c\cdot n\log_2 n\)
\(t(n) = O(n\log n)\)
K
– число \(P\)-ичных разрядов в числе.
algorithm radix_sort(a[N])
for r from 1 to K
for j from 1 to P-1
c[j] := 0
end for i
for i from 1 to N
x := r-тый разряд a[i]
c[x] := c[x] + 1
end for i
for j from 1 to P-1
c[j] := c[j-1] + c[j]
end for i
for i from N to 1
x := r-тый разряд a[i]
c[x] := c[x] - 1
b[c[x]] := a[i]
end for i
a := b
end for r
end algorithm radix_sort
Часто в качестве \(P\) выбирается степень двойки, например \(2^8\), \(2^{16}\). В таком случае сводится к битовым операциям.