234
правки
Изменения
→Алгоритм Джарвиса
== Описание Алгоритма ==
1) Возьмем самую правую нижнюю точку <tex>p_0</tex> нашего множества. Добавляем ее в ответ. 2) На каждом следующем шаге для последнего добавленного <tex>p_i</tex> ищем <tex>p_{i + 1}</tex> среди всех недобавленных точек и <tex>p_0</tex> с максимальным полярным углом относительно <tex>p_i</tex> (Если углы равны, надо сравнивать по расстоянию). Добавляем <tex>p_{i + 1}</tex> в ответ. Если <tex>p_{i + 1} == p_0</tex> , заканчиваем алгоритм. == Корректность == Точка <tex>p_0</tex>, очевидно, принадлежит оболочке. На каждом шаге мы получаем прямую <tex>p_{i-1}p_i</tex>, по построениению которой все точки множества лежат слева от нее. Значит эти точки принадлежат выпуклой оболочке. == Псевдокод == Подаем в функцию исходное множество S, возвращаем позицию <tex>k</tex> - в <tex>S[1..k - 1]</tex> будет хранится наша оболочка.<tex>turn(a, b, c)</tex> - модифицированная функция поворота, учитывающая случай, когда точки лежат на одной прямой. Jarvis(S) for i = 1..n if S[i] is right and higher than S[1] swap(S[1], S[i]) k = 1 do for i = 1 and k+1..n if (turn(S[k+1], S[i], S[k])) swap(S[k+1], S[k]) k++; while S[k-1] != S[1] == Сложность == Добавление каждой точки в ответ занимает <tex>O(n)</tex> времени, всего точек будет <tex>k</tex>, поэтому итоговая сложность <tex>O(nk)</tex>.
= Алгоритм Грехэма =