<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zakirzyanov</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zakirzyanov"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Zakirzyanov"/>
		<updated>2026-06-08T19:36:28Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25405</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25405"/>
				<updated>2012-06-13T16:32:13Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' {{---}} алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка {{---}} два соседних по представлению значения в типе данных. Утверждается, что два числа {{---}} соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;amp;ndash;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;amp;ndash;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) == c                                 //**&lt;br /&gt;
            return mid;                                //**&lt;br /&gt;
        else if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Примеры использования ==&lt;br /&gt;
* Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x \ge 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней {{---}} &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Если функция нестрого монотонна, то, убрав из приведенного выше алгоритма строки, отмеченные &amp;lt;tex&amp;gt;(**)&amp;lt;/tex&amp;gt;, мы получим алгоритм, который будет находить &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; такой, что &amp;lt;tex&amp;gt;f(x) = c&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;f(x - \epsilon) &amp;lt; c&amp;lt;/tex&amp;gt;. &lt;br /&gt;
== Замечания ==&lt;br /&gt;
* Необходимо отметить, то функция должна быть строго монотонна, если мы ищем конкретный корень и он единственный. Нестрого монотонна, если нам необходимо найти самый левый (правый) аргумент. Если же функция не монотонна, то данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. &lt;br /&gt;
* Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25388</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25388"/>
				<updated>2012-06-12T19:59:27Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' {{---}} алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка {{---}} два соседних по представлению значения в типе данных. Утверждается, что два числа {{---}} соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;amp;ndash;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;amp;ndash;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x \ge 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней {{---}} &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25386</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25386"/>
				<updated>2012-06-12T19:52:27Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;amp;ndash;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;amp;ndash;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x \ge 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25385</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25385"/>
				<updated>2012-06-12T19:51:15Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;amp;ndash;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;amp;ndash;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x &amp;gt;= 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25382</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25382"/>
				<updated>2012-06-12T19:41:28Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;amp;ndash;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;amp;ndash;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;amp;ndash;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;/tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x &amp;gt;= 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25378</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25378"/>
				<updated>2012-06-12T19:25:18Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;-&amp;lt;/tex&amp;gt;  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;-&amp;lt;/tex&amp;gt;  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: &amp;lt;tex&amp;gt;-&amp;lt;/tex&amp;gt;  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: &amp;lt;tex&amp;gt;-&amp;lt;/tex&amp;gt;  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;/tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x &amp;gt;= 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25377</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25377"/>
				<updated>2012-06-12T19:09:38Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение аргумента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt; этой функции, в которой она принимает определенное значение &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: '''+''' Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: '''-'''  Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: '''+''' В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: '''-'''  Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: '''+''' Алгоритм найдет число с максимально возможной точностью.&lt;br /&gt;
: '''-'''  Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполнится только конечное число число итераций.&lt;br /&gt;
: '''+''' Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
: '''-'''  Довольно плохая точность, если границы отрезка находятся на большом расстоянии.&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;/tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x &amp;gt;= 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Замечания ==&lt;br /&gt;
Необходимо отметить, то функция должна быть строго монотонна, иначе данный алгоритм не найдет искомый аргумент, либо найдет аргумент, но он не будет единственным. Важным отличием от целочисленного поиска является то, что мы передвигаем границу ровно в середину отрезка (&amp;lt;tex&amp;gt;left = mid&amp;lt;/tex&amp;gt;), а не со смещением внутрь отрезка (&amp;lt;tex&amp;gt;left = mid + 1&amp;lt;/tex&amp;gt;). &lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25365</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25365"/>
				<updated>2012-06-12T17:34:45Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти значение (&amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt;) этой функции в заданной точке (&amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
[[Файл:Function.png]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу в середину отрезка. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
* Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
: &amp;lt;tex&amp;gt;\oplus&amp;lt;/tex&amp;gt; Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;\ominus&amp;lt;/tex&amp;gt; Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
* Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
: &amp;lt;tex&amp;gt;\oplus&amp;lt;/tex&amp;gt; В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
&lt;br /&gt;
: &amp;lt;tex&amp;gt;\ominus&amp;lt;/tex&amp;gt; Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
* Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
: &amp;lt;tex&amp;gt;\ominus&amp;lt;/tex&amp;gt; Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
* Итеративный способ. В этом способе выполниться только конечное число число итераций.&lt;br /&gt;
: &amp;lt;tex&amp;gt;\oplus&amp;lt;/tex&amp;gt; Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
&lt;br /&gt;
== Выбор границы отрезка для поиска==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например &amp;lt;/tex&amp;gt;1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку (например &amp;lt;tex&amp;gt;-1&amp;lt;/tex&amp;gt;). Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            left = mid;&lt;br /&gt;
        else&lt;br /&gt;
            right = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Пример использования ==&lt;br /&gt;
Классической задачей на вещественный двоичный поиск является задача поиска корня &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;-ой степени из числа &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;: &amp;lt;tex&amp;gt;\sqrt[n]{x}&amp;lt;/tex&amp;gt;. При &amp;lt;tex&amp;gt;x &amp;gt;= 1&amp;lt;/tex&amp;gt; нижней границей для поиска будет &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, а верхней - &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;.&lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Function.png&amp;diff=25356</id>
		<title>Файл:Function.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Function.png&amp;diff=25356"/>
				<updated>2012-06-12T17:15:10Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25320</id>
		<title>Вещественный двоичный поиск</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%92%D0%B5%D1%89%D0%B5%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%B4%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D1%8B%D0%B9_%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&amp;diff=25320"/>
				<updated>2012-06-12T15:40:34Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Вещественный двоичный поиск''' - алгоритм поиска аргумента для заданного значения монотонной вещественной функции.&lt;br /&gt;
&lt;br /&gt;
== Формулировка задачи == &lt;br /&gt;
Пусть нам задана монотонная функция. Необходимо найти место, где значение функции становится меньше, чем какое-то заданное значение.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[Файл:Functsia.GIF]]&lt;br /&gt;
&lt;br /&gt;
== Решение задачи ==&lt;br /&gt;
Применим идею двоичного поиска. Выберем такие границы, где значение функции точно больше и точно меньше заданного значения. Выберем значение в середине этого отрезка. Если оно меньше, чем заданное, то сместим левую границу. В противном случае сместим правую границу. Далее повторим процесс сужения границ. Встает вопрос, когда остановиться. Есть несколько способов сделать это.&lt;br /&gt;
&lt;br /&gt;
== Выбор границы ==&lt;br /&gt;
Для начала найдем правую границу. Выберем произвольную положительную точку (например 1). Будем удваивать ее до тех пор, пока значение функции в этой точке меньше заданного. Для того, чтобы найти левую границу выберем произвольную отрицательную точку. Будем удваивать ее до тех пор, пока значение в ней будет больше заданного значения.&lt;br /&gt;
&lt;br /&gt;
== Способы закончить поиск ==&lt;br /&gt;
# Первый способ заключается в том, чтобы остановиться, когда рассматриваемый отрезок станет меньше заданного эпсилон. Но у этого подхода есть свои плюсы и минусы:&lt;br /&gt;
#* Алгоритм с большой точностью найдет значение аргумента&lt;br /&gt;
#* Алгоритм может зациклиться. В компьютере мы работаем с конечным числом вещественных чисел. У чисел       есть точность. Соответственно при больших значениях функции, длина отрезка может никогда не уменьшиться до заданного значения&lt;br /&gt;
# Второй способ менее точен. Предлагается заканчивать алгоритм, когда значение функции на концах отрезках различается менее, чем на заданное эпсилон.&lt;br /&gt;
#* В отличии от предыдущего, не зацикливается при больших значениях функции.&lt;br /&gt;
#* Возможна большая погрешность, если функция будет очень медленно возрастать&lt;br /&gt;
# Абсолютно точный поиск. Вспомним о том, что вещественный числа в компьютере дискретным. Будем завершать поиск, когда границы отрезка - два соседних по представлению значения в типе данных. Утверждается, что два числа - соседние, если середина их отрезка совпадает или с левой, или с правой границей.&lt;br /&gt;
#* Возможно плохое поведение, если искомый аргумент равен 0.&lt;br /&gt;
# Итеративный способ. В этом способе выполниться только конечное число число итераций.&lt;br /&gt;
#* Плюсом этого способа является фиксированная погрешность.&lt;br /&gt;
&lt;br /&gt;
== Псевдокод ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findLeft(c) &lt;br /&gt;
    x = -1;&lt;br /&gt;
    while f(x) &amp;gt; c &lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
findRight(c)&lt;br /&gt;
    x = 1;&lt;br /&gt;
    while f(x) &amp;lt; c&lt;br /&gt;
        x = x * 2;&lt;br /&gt;
    return x;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
binSearch(c)&lt;br /&gt;
    left = findLeft(с);&lt;br /&gt;
    right = findRight(с);&lt;br /&gt;
    while left &amp;lt; right - eps                           //Здесь можно использовать другое условие выхода&lt;br /&gt;
        mid = (left + right) / 2;&lt;br /&gt;
        if f(mid) &amp;lt; c&lt;br /&gt;
            l = mid;&lt;br /&gt;
        else&lt;br /&gt;
            r = mid;&lt;br /&gt;
    return l;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
== Источники == &lt;br /&gt;
* [http://www.intuit.ru/department/algorithms/basicalgos/2/ Интернет университет, лекция сортировка и поиск]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=25205</id>
		<title>Дискретная математика, алгоритмы и структуры данных</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%B0%D1%8F_%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0,_%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%D1%8B_%D0%B8_%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D1%83%D1%80%D1%8B_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85&amp;diff=25205"/>
				<updated>2012-06-12T11:14:45Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: /* Амортизационный анализ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Категория:Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
&lt;br /&gt;
Убедительная просьба читать [[Обсуждение:Дискретная_математика_и_алгоритмы | правила оформления вики-конспектов]].&lt;br /&gt;
&lt;br /&gt;
= Первый семестр =&lt;br /&gt;
&lt;br /&gt;
== Отношения ==&lt;br /&gt;
*[[Определение отношения]]&lt;br /&gt;
*[[Степень отношений]]&lt;br /&gt;
*[[Рефлексивное отношение|Рефлексивное отношение. Антирефлексивное отношение.]]&lt;br /&gt;
*[[Симметричное отношение]]&lt;br /&gt;
*[[Антисимметричное отношение]]&lt;br /&gt;
*[[Композиция отношений|Композиция отношений. Обратное отношение]]&lt;br /&gt;
*[[Транзитивное отношение]]&lt;br /&gt;
*[[Транзитивное замыкание|Транзитивное замыкание отношения]]&lt;br /&gt;
*[[Транзитивный остов]]&lt;br /&gt;
*[[Отношение порядка]]&lt;br /&gt;
*[[Отношение эквивалентности]]&lt;br /&gt;
*[[Алгоритм Флойда — Уоршелла|Алгоритм Флойда-Уоршалла построения транзитивного замыкания отношения]]&lt;br /&gt;
&lt;br /&gt;
== Булевы функции ==&lt;br /&gt;
*[[Определение булевой функции]]&lt;br /&gt;
*[[Суперпозиции]]&lt;br /&gt;
*[[ДНФ]]&lt;br /&gt;
*[[КНФ]]&lt;br /&gt;
*[[Полином Жегалкина]]&lt;br /&gt;
*[[Полные системы функций. Теорема Поста о полной системе функций]]&lt;br /&gt;
*[[Сокращенная и минимальная ДНФ]]&lt;br /&gt;
*[[Минимизация ДНФ с помощью покрытий гиперкуба и карт Карно]]&lt;br /&gt;
*[[Специальные формы КНФ|Специальные формы КНФ: КНФ в форме Хорна и КНФ в форме Крома]]&lt;br /&gt;
*[[Преобразование Мёбиуса для получения коэффициентов полинома Жегалкина]]&lt;br /&gt;
*[[Представление функции класса DM с помощью медианы]]&lt;br /&gt;
*[[Пороговая функция]]&lt;br /&gt;
&lt;br /&gt;
== Схемы из функциональных элементов ==&lt;br /&gt;
*[[Реализация булевой функции схемой из функциональных элементов]]&lt;br /&gt;
*[[Cумматор]]&lt;br /&gt;
*[[Каскадный сумматор]]&lt;br /&gt;
*[[Двоичный каскадный сумматор]]&lt;br /&gt;
*[[Реализация вычитания сумматором]]&lt;br /&gt;
*[[Матричный умножитель]]&lt;br /&gt;
*[[Дерево Уоллеса]]&lt;br /&gt;
&lt;br /&gt;
== Представление информации ==&lt;br /&gt;
*[[Кодирование информации]]&lt;br /&gt;
*[[Представление целых чисел: прямой код, код со сдвигом, дополнительный код]]&lt;br /&gt;
*[[Представление вещественных чисел]]&lt;br /&gt;
*[[Представление символов, таблицы кодировок]]&lt;br /&gt;
&lt;br /&gt;
== Алгоритмы сжатия ==&lt;br /&gt;
*[[Алгоритм Хаффмана]]&lt;br /&gt;
*[[Алгоритм LZW]]&lt;br /&gt;
*[[Алгоритмы LZ77 и LZ78]]&lt;br /&gt;
*[[Преобразование Барроуза-Уиллера]]&lt;br /&gt;
*[[Обратное преобразование Барроуза-Уиллера]]&lt;br /&gt;
*[[Преобразование MTF]]&lt;br /&gt;
*[[Расстояние Хэмминга]]&lt;br /&gt;
*[[Избыточное кодирование, код Хэмминга]]&lt;br /&gt;
*[[Неравенство Крафта]]&lt;br /&gt;
*[[Неравенство Макмиллана]]&lt;br /&gt;
&lt;br /&gt;
== Комбинаторика ==&lt;br /&gt;
*[[Комбинаторные объекты]]&lt;br /&gt;
*[[Лексикографический порядок]]&lt;br /&gt;
*[[Формула включения-исключения]]&lt;br /&gt;
*[[Генерация комбинаторных объектов в лексикографическом порядке]]&lt;br /&gt;
*[[Получение номера по объекту]]&lt;br /&gt;
*[[Получение объекта по номеру]]&lt;br /&gt;
*[[Получение следующего объекта]]&lt;br /&gt;
*[[Коды Грея]]&lt;br /&gt;
*[[Коды Грея для перестановок]]&lt;br /&gt;
*[[Цепные коды]]&lt;br /&gt;
*[[Правильные скобочные последовательности]]&lt;br /&gt;
*[[Действие перестановки на набор из элементов, представление в виде циклов]]&lt;br /&gt;
*[[Метод генерации случайной перестановки, алгоритм Фишера-Йетса]]&lt;br /&gt;
*[[Таблица инверсий]]&lt;br /&gt;
*[[Умножение перестановок, обратная перестановка, группа перестановок]]&lt;br /&gt;
*[[Теорема Кэли]]&lt;br /&gt;
*[[Матричное представление перестановок]]&lt;br /&gt;
*[[Задача о минимуме/максимуме скалярного произведения]]&lt;br /&gt;
*[[Задача о монотонных подпоследовательностях, теорема о связи длины НВП и НУП]]&lt;br /&gt;
*[[Нахождение количества разбиений числа на слагаемые | Нахождение количества разбиений числа на слагаемые. Пентагональная теорема Эйлера]]&lt;br /&gt;
*[[Производящая функция]]&lt;br /&gt;
&lt;br /&gt;
== [[Динамическое программирование]] ==&lt;br /&gt;
*[[Кратчайший путь в ациклическом графе]]&lt;br /&gt;
*[[Задача о расстановке знаков в выражении]]&lt;br /&gt;
*[[Задача о наибольшей общей подпоследовательности]]&lt;br /&gt;
*[[Задача о порядке перемножения матриц]]&lt;br /&gt;
*[[Задача о наибольшей возрастающей подпоследовательности]]&lt;br /&gt;
*[[Задача о паросочетании максимального веса в дереве, амортизированные оценки для ДП на дереве]]&lt;br /&gt;
*[[Метод четырех русских для умножения матриц]]&lt;br /&gt;
*[[Применение метода четырех русских в задачах ДП на примере задачи о НОП]]&lt;br /&gt;
*[[Задача коммивояжера, ДП по подмножествам]]&lt;br /&gt;
*[[Задача о выводе в контекстно-свободной грамматике, алгоритм Кока-Янгера-Касами]]&lt;br /&gt;
*[[Задача о редакционном расстоянии, алгоритм Вагнера-Фишера]]&lt;br /&gt;
*[[Задача о расстоянии Дамерау-Левенштейна]]&lt;br /&gt;
*[[Задача об оптимальном префиксном коде с сохранением порядка. Монотонность точки разреза]]&lt;br /&gt;
&lt;br /&gt;
== Теория вероятностей ==&lt;br /&gt;
*[[Вероятностное пространство, элементарный исход, событие]]&lt;br /&gt;
*[[Независимые события]]&lt;br /&gt;
*[[Условная вероятность]]&lt;br /&gt;
*[[Формула Байеса]]&lt;br /&gt;
*[[Формула полной вероятности]]&lt;br /&gt;
*[[Дискретная случайная величина]]&lt;br /&gt;
*[[Независимые случайные величины]]&lt;br /&gt;
*[[Математическое ожидание случайной величины]]&lt;br /&gt;
*[[Ковариация случайных величин]]&lt;br /&gt;
*[[Дисперсия случайной величины]]&lt;br /&gt;
*[[Энтропия случайного источника]]&lt;br /&gt;
*[[Симуляция одним распределением другого]]&lt;br /&gt;
*[[Арифметическое кодирование]]&lt;br /&gt;
*[[Задача о двух конвертах]]&lt;br /&gt;
&lt;br /&gt;
== Марковские цепи ==&lt;br /&gt;
&lt;br /&gt;
* [[Марковская цепь]]&lt;br /&gt;
* [[Теорема о поглощении]]&lt;br /&gt;
* [[Фундаментальная матрица]]&lt;br /&gt;
* [[Математическое ожидание времени поглощения]]&lt;br /&gt;
* [[Расчет вероятности поглощения в состоянии]]&lt;br /&gt;
* [[Эргодическая марковская цепь]]&lt;br /&gt;
* [[Регулярная марковская цепь]]&lt;br /&gt;
&lt;br /&gt;
= Второй семестр =&lt;br /&gt;
&lt;br /&gt;
== Амортизационный анализ ==&lt;br /&gt;
* [[Амортизационный анализ]]&lt;br /&gt;
* [[Саморасширяющийся массив]]&lt;br /&gt;
* [[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
* [[Список]]&lt;br /&gt;
* [[Стек]]&lt;br /&gt;
* [[Очередь]]&lt;br /&gt;
* [[Персистентный стек]]&lt;br /&gt;
* [[Персистентный дек]]&lt;br /&gt;
&lt;br /&gt;
== Приоритетные очереди ==&lt;br /&gt;
&lt;br /&gt;
* [[Двоичная куча]]&lt;br /&gt;
* [[Биномиальная куча]]&lt;br /&gt;
* [[Фибоначчиева куча]]&lt;br /&gt;
&lt;br /&gt;
== Система непересекающихся множеств ==&lt;br /&gt;
* [[СНМ (наивные реализации) | Наивные реализации]]&lt;br /&gt;
* [[СНМ (списки с весовой эвристикой) | Списки с весовой эвристикой]]&lt;br /&gt;
* [[СНМ(реализация с помощью леса корневых деревьев) | Реализация с помощью леса корневых деревьев]]&lt;br /&gt;
&lt;br /&gt;
== Поисковые структуры данных ==&lt;br /&gt;
* [[Упорядоченное множество]]&lt;br /&gt;
* [[Дерево поиска, наивная реализация]]&lt;br /&gt;
* [[АВЛ-дерево]]&lt;br /&gt;
* [[2-3 дерево]]&lt;br /&gt;
* [[B-дерево]]&lt;br /&gt;
* [[Красно-черное дерево]]&lt;br /&gt;
* [[Декартово дерево]]&lt;br /&gt;
* [[Splay-дерево]]&lt;br /&gt;
* [[Декартово дерево по неявному ключу]]&lt;br /&gt;
* [[Дерево ван Эмде Боаса]]&lt;br /&gt;
* [[Рандомизированное бинарное дерево поиска]]&lt;br /&gt;
* [[Список с пропусками]]&lt;br /&gt;
&lt;br /&gt;
== Дерево отрезков ==&lt;br /&gt;
&lt;br /&gt;
* [[Статистики на отрезках. Корневая эвристика]]&lt;br /&gt;
* [[Дерево отрезков. Построение]]&lt;br /&gt;
* [[Реализация запроса в дереве отрезков сверху]]&lt;br /&gt;
* [[Реализация запроса в дереве отрезков снизу]]&lt;br /&gt;
* [[Несогласованные поддеревья. Реализация массового обновления]]&lt;br /&gt;
* [[Многомерное дерево отрезков]]&lt;br /&gt;
* [[Сжатое многомерное дерево отрезков]]&lt;br /&gt;
&lt;br /&gt;
== Дерево Фенвика ==&lt;br /&gt;
* [[Дерево Фенвика]]&lt;br /&gt;
* [[Встречное дерево Фенвика]]&lt;br /&gt;
* [[Дерево Фенвика для некоммутативных операций]]&lt;br /&gt;
* [[Многомерное дерево Фенвика]]&lt;br /&gt;
&lt;br /&gt;
== Хеширование ==&lt;br /&gt;
* [[Хеш-таблица]]&lt;br /&gt;
* [[Хеширование]]&lt;br /&gt;
* [[Открытое и закрытое хеширование]]&lt;br /&gt;
* [[Поиск свободного места при закрытом хешировании]]&lt;br /&gt;
* [[Хеширование кукушки]]&lt;br /&gt;
* [[Двойное хеширование]]&lt;br /&gt;
* [[Перехеширование. Амортизационный анализ]]&lt;br /&gt;
* [[Фильтр Блума]]&lt;br /&gt;
* [[Универсальное семейство хеш-функций]]&lt;br /&gt;
&lt;br /&gt;
== [[Сортировка]] ==&lt;br /&gt;
* [[Сортировка выбором]]&lt;br /&gt;
* [[Сортировка пузырьком]]&lt;br /&gt;
* [[Сортировка слиянием]]&lt;br /&gt;
* [[Cортировка слиянием с использованием O(1) дополнительной памяти]]&lt;br /&gt;
* [[Сортировка вставками]]&lt;br /&gt;
* [[Сортировка подсчетом]]&lt;br /&gt;
* [[Сортировка подсчетом сложных объектов]]&lt;br /&gt;
* [[Сортировка кучей]]&lt;br /&gt;
* [[Цифровая сортировка]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики]]&lt;br /&gt;
* [[Поиск k-ой порядковой статистики за линейное время]]&lt;br /&gt;
* [[Теорема о нижней оценке для сортировки сравнениями]]&lt;br /&gt;
* [[Быстрая сортировка]]&lt;br /&gt;
* [[Карманная сортировка]]&lt;br /&gt;
&lt;br /&gt;
== Сортирующие сети ==&lt;br /&gt;
* [[Сортирующие сети]]&lt;br /&gt;
* [[0-1 принцип | Проверка сети компараторов на то, что она сортирующая. 0-1 принцип]]&lt;br /&gt;
* [[Сортирующие сети для квадратичных сортировок]]&lt;br /&gt;
* [[Сеть Бетчера]]&lt;br /&gt;
&lt;br /&gt;
== Алгоритмы поиска ==&lt;br /&gt;
* [[Троичный поиск]]&lt;br /&gt;
* [[Поиск с помощью золотого сечения]]&lt;br /&gt;
* [[Интерполяционный поиск]]&lt;br /&gt;
* [[Вещественный двоичный поиск]]&lt;br /&gt;
* [[Целочисленный двоичный поиск]]&lt;br /&gt;
&lt;br /&gt;
== Связь между структурами данных ==&lt;br /&gt;
* [[Связь между структурами данных]]&lt;br /&gt;
&lt;br /&gt;
= Третий семестр =&lt;br /&gt;
&lt;br /&gt;
== Основные определения теории графов ==&lt;br /&gt;
* [[Основные определения теории графов|Основные определения: граф, ребро, вершина, степень, петля, путь, цикл]]&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Теорема о существовании простого пути в случае существования пути]]&lt;br /&gt;
* [[Теорема о существовании простого цикла в случае существования цикла]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Связь степени матрицы смежности и количества путей]]&lt;br /&gt;
* [[Матрица инцидентности графа]]&lt;br /&gt;
* [[Циклическое пространство графа]]&lt;br /&gt;
* [[Фундаментальные циклы графа]]&lt;br /&gt;
* [[Дерево, эквивалентные определения]]&lt;br /&gt;
&lt;br /&gt;
== Связность в графах ==&lt;br /&gt;
* [[Отношение связности, компоненты связности]]&lt;br /&gt;
* [[Отношение реберной двусвязности]]&lt;br /&gt;
* [[Отношение вершинной двусвязности]]&lt;br /&gt;
* [[Граф компонент реберной двусвязности]]&lt;br /&gt;
* [[Граф блоков-точек сочленения]]&lt;br /&gt;
* [[Точка сочленения, эквивалентные определения]]&lt;br /&gt;
* [[Мост, эквивалентные определения]]&lt;br /&gt;
* [[k-связность]]&lt;br /&gt;
* [[Теорема Менгера]]&lt;br /&gt;
* [[Теорема Менгера, альтернативное доказательство]]&lt;br /&gt;
* [[Вершинная, реберная связность, связь между ними и минимальной степенью вершины]]&lt;br /&gt;
&lt;br /&gt;
== Остовные деревья ==&lt;br /&gt;
* [[Матрица Кирхгофа]]&lt;br /&gt;
* [[Связь матрицы Кирхгофа и матрицы инцидентности]]&lt;br /&gt;
* [[Подсчет числа остовных деревьев с помощью матрицы Кирхгофа]]&lt;br /&gt;
* [[Количество помеченных деревьев]]&lt;br /&gt;
* [[Коды Прюфера]]&lt;br /&gt;
&lt;br /&gt;
== Обходы графов ==&lt;br /&gt;
* [[Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов]]&lt;br /&gt;
* [[Покрытие ребер графа путями]]&lt;br /&gt;
* [[Алгоритм построения Эйлерова цикла]]&lt;br /&gt;
* [[Произвольно вычерчиваемые из заданной вершины графы]]&lt;br /&gt;
* [[Гамильтоновы графы]]&lt;br /&gt;
* [[Теорема Хватала]]&lt;br /&gt;
* Следствия теоремы Хватала: &lt;br /&gt;
** [[Теорема Дирака]]&lt;br /&gt;
* [[Теорема Оре]]&lt;br /&gt;
* [[Турниры]]&lt;br /&gt;
* [[Теорема Редеи-Камиона]]&lt;br /&gt;
&lt;br /&gt;
== Укладки графов ==&lt;br /&gt;
* [[Укладка графа на плоскости]]&lt;br /&gt;
* [[Формула Эйлера]]&lt;br /&gt;
* [[Непланарность K5 и K3,3|Непланарность &amp;lt;tex&amp;gt;K_5&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;K_{3,3}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[Укладка дерева]]&lt;br /&gt;
* [[Укладка графа с планарными компонентами реберной двусвязности]]&lt;br /&gt;
* [[Укладка графа с планарными компонентами вершинной двусвязности]]&lt;br /&gt;
* [[Теорема Понтрягина-Куратовского]]&lt;br /&gt;
* [[Двойственный граф планарного графа]]&lt;br /&gt;
&lt;br /&gt;
== Раскраски графов ==&lt;br /&gt;
* [[Раскраска графа]]&lt;br /&gt;
* [[Двудольные графы и раскраска в 2 цвета]]&lt;br /&gt;
* [[Хроматический многочлен]]&lt;br /&gt;
** [[Хроматический многочлен#Хроматический многочлен полного графа|Хроматический многочлен полного графа]]&lt;br /&gt;
** [[Хроматический многочлен#Хроматический многочлен пустого графа|Хроматический многочлен пустого графа]]&lt;br /&gt;
** [[Хроматический многочлен#Хроматический многочлен дерева|Хроматический многочлен дерева]]&lt;br /&gt;
** [[Хроматический многочлен#Рекуррентные формулы для хроматических многочленов|Рекуррентные формулы для хроматических многочленов]]&lt;br /&gt;
** [[Хроматический многочлен#Коэффициенты хроматического многочлена|Коэффициенты хроматического многочлена: старший, второй коэффициенты, знакопеременность]]&lt;br /&gt;
* [[Формула Зыкова]]&lt;br /&gt;
* [[Формула Уитни]]&lt;br /&gt;
&lt;br /&gt;
== Обход в глубину ==&lt;br /&gt;
* [[Обход в глубину, цвета вершин]]&lt;br /&gt;
* [[Лемма о белых путях]]&lt;br /&gt;
* [[Использование обхода в глубину для проверки связности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска цикла в ориентированном графе]]&lt;br /&gt;
* [[Использование обхода в глубину для топологической сортировки]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска компонент сильной связности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска точек сочленения]]&lt;br /&gt;
* [[Построение компонент вершинной двусвязности]]&lt;br /&gt;
* [[Использование обхода в глубину для поиска мостов]]&lt;br /&gt;
* [[Построение компонент реберной двусвязности]]&lt;br /&gt;
&lt;br /&gt;
== Кратчайшие пути в графах ==&lt;br /&gt;
* [[Обход в ширину]]&lt;br /&gt;
* [[Алгоритм Форда-Беллмана]]&lt;br /&gt;
* [[Алгоритм Дейкстры]]&lt;br /&gt;
* [[Алгоритм Флойда]]&lt;br /&gt;
* [[Алгоритм A*]]&lt;br /&gt;
* [[Алгоритм Джонсона]]&lt;br /&gt;
&lt;br /&gt;
== Остовные деревья ==&lt;br /&gt;
* [[Лемма о безопасном ребре]]&lt;br /&gt;
* [[Алгоритм Прима]]&lt;br /&gt;
* [[Алгоритм Краскала]]&lt;br /&gt;
* [[Критерий Тарьяна минимальности остовного дерева|Теорема Тарьяна (критерий минимальности остовного дерева)]]&lt;br /&gt;
* [[Алгоритм двух китайцев]]&lt;br /&gt;
&lt;br /&gt;
== Задача о паросочетании ==&lt;br /&gt;
* [[Теорема о максимальном паросочетании и дополняющих цепях]]&lt;br /&gt;
* [[Алгоритм Форда-Фалкерсона для поиска максимального паросочетания]]&lt;br /&gt;
* [[Алгоритм Куна для поиска максимального паросочетания]]&lt;br /&gt;
* [[Связь максимального паросочетания и минимального вершинного покрытия в двудольных графах]]&lt;br /&gt;
* [[Связь вершинного покрытия и независимого множества]]&lt;br /&gt;
* [[Матрица Татта и связь с размером максимального паросочетания в двудольном графе]]&lt;br /&gt;
* [[Алгоритм вырезания соцветий|Паросочетания в недвудольных графах. Алгоритм вырезания соцветий]]&lt;br /&gt;
&lt;br /&gt;
== Задача о максимальном потоке ==&lt;br /&gt;
* [[Определение сети, потока]]&lt;br /&gt;
* [[Разрез, лемма о потоке через разрез]]&lt;br /&gt;
* [[Дополняющая сеть, дополняющий путь]]&lt;br /&gt;
* [[Лемма о сложении потоков]]&lt;br /&gt;
* [[Теорема Форда-Фалкерсона]]&lt;br /&gt;
* [[Алгоритм Форда-Фалкерсона, реализация с помощью поиска в глубину]]&lt;br /&gt;
* [[Алоритм Эдмондса-Карпа]]&lt;br /&gt;
* [[Теорема о декомпозиции]]&lt;br /&gt;
* [[Теорема о декомпозиционном барьере]]&lt;br /&gt;
* [[Блокирующий поток]]&lt;br /&gt;
* [[Схема алгоритма Диница]]&lt;br /&gt;
* [[Циркуляция потока]]&lt;br /&gt;
* [[Алгоритм поиска блокирующего потока в ациклической сети]]&lt;br /&gt;
* [[Алгоритм масштабирования потока]]&lt;br /&gt;
* [[Теоремы Карзанова о числе итераций алгоритма Диница в сети с целочисленными пропускными способностями]]&lt;br /&gt;
&lt;br /&gt;
== Задача о потоке минимальной стоимости ==&lt;br /&gt;
* [[Поток минимальной стоимости]]&lt;br /&gt;
* [[Теорема Форда-Фалкерсона о потоке минимальной стоимости]]&lt;br /&gt;
* [[Лемма об эквивалентности свойства потока быть минимальной стоимости и отсутствии отрицательных циклов в остаточной сети]]&lt;br /&gt;
* [[Поиск потока минимальной стоимости методом дополнения вдоль путей минимальной стоимости]]&lt;br /&gt;
* [[Использование потенциалов Джонсона при поиске потока минимальной стоимости]]&lt;br /&gt;
* [[Сведение задачи о назначениях к задаче о потоке минимальной стоимости]]&lt;br /&gt;
* [[Венгерский алгоритм решения задачи о назначениях]]&lt;br /&gt;
&lt;br /&gt;
= Четвертый семестр =&lt;br /&gt;
&lt;br /&gt;
== Основные определения. Простые комбинаторные свойства слов ==&lt;br /&gt;
* [[Основные определения, связанные со строками]]&lt;br /&gt;
* [[Период и бордер, их связь]]&lt;br /&gt;
* [[Слово Фибоначчи]]&lt;br /&gt;
* [[Слово Туэ-Морса]]&lt;br /&gt;
&lt;br /&gt;
== Поиск подстроки в строке ==&lt;br /&gt;
* [[Наивный алгоритм поиска подстроки в строке]]&lt;br /&gt;
* [[Поиск подстроки в строке с использованием хеширования. Алгоритм Рабина-Карпа]]&lt;br /&gt;
* [[Поиск наибольшей общей подстроки двух строк с использованием хеширования]]&lt;br /&gt;
* [[Префикс-функция]]&lt;br /&gt;
* [[Алгоритм Кнута-Морриса-Пратта]]&lt;br /&gt;
* [[Z-функция]]&lt;br /&gt;
* [[Автомат для поиска образца в тексте]]&lt;br /&gt;
* [[Бор]]&lt;br /&gt;
* [[Алгоритм Ахо-Корасик]]&lt;br /&gt;
&lt;br /&gt;
== Суффиксное дерево ==&lt;br /&gt;
* [[Суффиксный бор]]&lt;br /&gt;
* [[Сжатое суффиксное дерево]]&lt;br /&gt;
* [[Алгоритм Укконена]]&lt;br /&gt;
&lt;br /&gt;
=== Суффиксный массив ===&lt;br /&gt;
* [[Суффиксный массив]]&lt;br /&gt;
* [[Построение суффиксного массива с помощью стандартных методов сортировки]]&lt;br /&gt;
* [[Цифровая сортировка]]&lt;br /&gt;
* [[Алгоритм цифровой сортировки суффиксов циклической строки]]&lt;br /&gt;
* [[Алгоритм Касаи и др.]]&lt;br /&gt;
* [[Алгоритм Карккайнена-Сандерса]]&lt;br /&gt;
* [[Алгоритм поиска подстроки в строке с помощью суффиксного массива]]&lt;br /&gt;
&lt;br /&gt;
== Задача о наименьшем общем предке ==&lt;br /&gt;
* [[Метод двоичного подъема]]&lt;br /&gt;
* [[Сведение задачи LCA к задаче RMQ]]&lt;br /&gt;
* [[Решение RMQ с помощью разреженной таблицы]]&lt;br /&gt;
* [[Алгоритм Фарака-Колтона и Бендера]] (решение +/-1 RMQ с помощью метода четверых русских)&lt;br /&gt;
* [[Сведение задачи RMQ к задаче LCA]]&lt;br /&gt;
&lt;br /&gt;
== Матроиды ==&lt;br /&gt;
* [[Определение матроида]]&lt;br /&gt;
* [[Примеры матроидов]]&lt;br /&gt;
* [[Прямая сумма матроидов]]&lt;br /&gt;
* [[Теорема Радо-Эдмондса (жадный алгоритм)]]&lt;br /&gt;
* [[Жадный алгоритм поиска базы минимального веса]]&lt;br /&gt;
* [[Теорема о базах]]&lt;br /&gt;
* [[Аксиоматизация матроида базами]]&lt;br /&gt;
* [[Теорема о циклах]]&lt;br /&gt;
* [[Аксиоматизация матроида циклами]]&lt;br /&gt;
* [[Ранговая функция, полумодулярность]]&lt;br /&gt;
* [[Двойственный матроид]]&lt;br /&gt;
* [[Оператор замыкания для матроидов]]&lt;br /&gt;
* [[Пересечение матроидов, определение, примеры]]&lt;br /&gt;
* [[Лемма о паросочетании в графе замен]]&lt;br /&gt;
* [[Лемма о единственном паросочетании в графе замен]]&lt;br /&gt;
* [[Граф замен для двух матроидов]]&lt;br /&gt;
* [[Лемма о единственном паросочетании в подграфе замен, индуцированном кратчайшим путем]]&lt;br /&gt;
* [[Алгоритм построения базы в пересечении матроидов]]&lt;br /&gt;
* [[Теорема Эдмондса-Лоулера]]&lt;br /&gt;
* [[Объединение матроидов, проверка множества на независимость]]&lt;br /&gt;
* [[Объединение матроидов, доказательство того, что объединение является матроидом]]&lt;br /&gt;
* [[Алгоритм построения базы в объединении матроидов]]&lt;br /&gt;
==Теория расписаний==&lt;br /&gt;
* [[Классификация задач]]&lt;br /&gt;
* [[Методы решения задач теории расписаний]]&lt;br /&gt;
* [[Правило Лаулера]]&lt;br /&gt;
* [[1precpmtnrifmax|&amp;lt;tex&amp;gt;1 \mid prec, pmtn, r_i \mid f_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnCmax|&amp;lt;tex&amp;gt;Q \mid pmtn \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[QpmtnriLmax|&amp;lt;tex&amp;gt;Q \mid pmtn, r_{i} \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[P2precpi1Lmax|&amp;lt;tex&amp;gt;P2 \mid prec, p_i = 1 \mid L_{\max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[O2Cmax|&amp;lt;tex&amp;gt;O2 \mid \mid C_{max}&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
* [[PpmtnriLmax|&amp;lt;tex&amp;gt;P \mid pmtn, r_i \mid L_{max}&amp;lt;/tex&amp;gt;]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap6.png&amp;diff=24808</id>
		<title>Файл:Heap6.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap6.png&amp;diff=24808"/>
				<updated>2012-06-10T16:38:24Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap6.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap5.png&amp;diff=24807</id>
		<title>Файл:Heap5.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap5.png&amp;diff=24807"/>
				<updated>2012-06-10T16:37:50Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap5.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap4.png&amp;diff=24804</id>
		<title>Файл:Heap4.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap4.png&amp;diff=24804"/>
				<updated>2012-06-10T16:35:23Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap4.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24803</id>
		<title>Файл:Heap3.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24803"/>
				<updated>2012-06-10T16:34:44Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap3.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24802</id>
		<title>Файл:Heap3.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24802"/>
				<updated>2012-06-10T16:34:22Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap3.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap2.png&amp;diff=24800</id>
		<title>Файл:Heap2.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap2.png&amp;diff=24800"/>
				<updated>2012-06-10T16:33:37Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap2.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap1.png&amp;diff=24799</id>
		<title>Файл:Heap1.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap1.png&amp;diff=24799"/>
				<updated>2012-06-10T16:32:21Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:Heap1.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=24746</id>
		<title>Сортировка кучей</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=24746"/>
				<updated>2012-06-10T13:34:35Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка кучей''', '''пирамидальная сортировка''' (англ. '''Heapsort''') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это неустойчивый алгоритм сортировки с временем работы &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов для сортировки, и использующий &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; дополнительной памяти.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Необходимо отсортировать массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, размером &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Построим на базе этого массива за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, он встанет на свое место. Далее вызовем процедуру &amp;lt;tex&amp;gt;sift\_down(0)&amp;lt;/tex&amp;gt;, предварительно уменьшив &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Она за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; просеет &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; на нужное место и сформирует новую кучу (так как мы уменьшили ее размер, то куча располагается с &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;A[n - 2]&amp;lt;/tex&amp;gt;, а элемент &amp;lt;tex&amp;gt;A[n-1]&amp;lt;/tex&amp;gt; находится на своем месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, а с &amp;lt;tex&amp;gt;A[n-2]&amp;lt;/tex&amp;gt;. Делая аналогичные действия, пока &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; не станет равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.&lt;br /&gt;
&lt;br /&gt;
== Реализация ==&lt;br /&gt;
&amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} массив, который необходимо отсортировать; &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов в нем; &amp;lt;tex&amp;gt;build\_heap(A)&amp;lt;/tex&amp;gt; - процедура, которая строит из передаваемого массива невозрастающую кучу в этом же массиве; &amp;lt;tex&amp;gt;sift\_down(A, i, len)&amp;lt;/tex&amp;gt; {{---}} процедура, которая просеивает вниз элемент &amp;lt;tex&amp;gt;A[i]&amp;lt;/tex&amp;gt; в куче из &amp;lt;tex&amp;gt;len&amp;lt;/tex&amp;gt; элементов, находящихся в начале массива &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
heapsort(A)&lt;br /&gt;
  build_heap(A);&lt;br /&gt;
  heap_size = A.size;&lt;br /&gt;
  for i = 0 to n - 2&lt;br /&gt;
    swap(A[0], A[n - 1 - i]);&lt;br /&gt;
    heap_size--;&lt;br /&gt;
    sift_down(A, 0, heap_size);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сложность ==&lt;br /&gt;
Операция &amp;lt;tex&amp;gt;sift\_down&amp;lt;/tex&amp;gt; работает за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. Всего цикл выполняется &amp;lt;tex&amp;gt;(n - 1)&amp;lt;/tex&amp;gt; раз. Таким образом сложность сортировки кучей является &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
{|align=&amp;quot;right&amp;quot;&lt;br /&gt;
 |-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |[[Файл:heap1.png|155px|thumb|Строим кучу]]&lt;br /&gt;
 |[[Файл:heap2.png|155px|thumb|Первый проход]]&lt;br /&gt;
 |[[Файл:heap3.png|155px|thumb|Строим новую кучу]]&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Файл:heap4.png|155px|thumb|Второй проход]]&lt;br /&gt;
 |[[Файл:heap5.png|155px|thumb|Третий проход]]&lt;br /&gt;
 |[[Файл:heap6.png|155px|thumb|Четвертый проход]]&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Пусть дана последовательность из &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;3, 2, 4, 1, 5&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;background-color:#CCC;margin:0.5px&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Массив&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 5 3 4 1 2&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из исходного массива &lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 3 4 1 '''5'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и последний элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''4''' 3 2 1 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых четырех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' 3 2 '''4''' 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и четвертый элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''3''' 1 2 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых трех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Третий проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 '''3''' 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и третий элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из двух элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' '''2''' 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и второй элементы  &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 1 2 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Массив отсортирован&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки == &lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%9F%D0%B8%D1%80%D0%B0%D0%BC%D0%B8%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0 Пирамидальная сортировка - Википедия]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Heapsort Heapsort - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
*''Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К.'' Алгоритмы: построение и анализ, 2-е издание. М.: Издательский дом &amp;quot;Вильямс&amp;quot;, 2005. ISBN 5-8459-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=24745</id>
		<title>Сортировка кучей</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=24745"/>
				<updated>2012-06-10T13:31:40Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка кучей''', '''пирамидальная сортировка''' (англ. '''Heapsort''') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это неустойчивый алгоритм сортировки с временем работы &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов для сортировки, и использующий &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; дополнительной памяти.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Необходимо отсортировать массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, размером &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Построим на базе этого массива за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, он встанет на свое место. Далее вызовем процедуру &amp;lt;tex&amp;gt;sift\_down(0)&amp;lt;/tex&amp;gt;, предварительно уменьшив &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Она за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; просеет &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; на нужное место и сформирует новую кучу (так как мы уменьшили ее размер, то куча располагается с &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;A[n - 2]&amp;lt;/tex&amp;gt;, а элемент &amp;lt;tex&amp;gt;A[n-1]&amp;lt;/tex&amp;gt; находится на своем месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, а с &amp;lt;tex&amp;gt;A[n-2]&amp;lt;/tex&amp;gt;. Делая аналогичные действия, пока &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; не станет равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.&lt;br /&gt;
&lt;br /&gt;
== Реализация ==&lt;br /&gt;
&amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} массив, который необходимо отсортировать; &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов в нем; &amp;lt;tex&amp;gt;build\_heap(A)&amp;lt;/tex&amp;gt; - процедура, которая строит из передаваемого массива невозрастающую кучу в этом же массиве; &amp;lt;tex&amp;gt;sift\_down(A, i, len)&amp;lt;/tex&amp;gt; {{---}} процедура, которая просеивает вниз элемент &amp;lt;tex&amp;gt;A[i]&amp;lt;/tex&amp;gt; в куче из &amp;lt;tex&amp;gt;len&amp;lt;/tex&amp;gt; элементов, находящихся в начале массива &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
heapsort(A)&lt;br /&gt;
  build_heap(A);&lt;br /&gt;
  heap_size = A.size;&lt;br /&gt;
  for i = 0 to n - 2&lt;br /&gt;
    swap(A[0], A[n - 1 - i]);&lt;br /&gt;
    heap_size--;&lt;br /&gt;
    sift_down(A, 0, heap_size);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сложность ==&lt;br /&gt;
Операция &amp;lt;tex&amp;gt;sift\_down&amp;lt;/tex&amp;gt; работает за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. Всего цикл выполняется &amp;lt;tex&amp;gt;(n - 1)&amp;lt;/tex&amp;gt; раз. Таким образом сложность сортировки кучей является &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
{|align=&amp;quot;right&amp;quot;&lt;br /&gt;
 |-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |[[Файл:heap1.png|180px|thumb|Строим кучу]]&lt;br /&gt;
 |[[Файл:heap2.png|180px|thumb|Первый проход]]&lt;br /&gt;
 |[[Файл:heap3.png|180px|thumb|Строим новую кучу]]&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Файл:heap4.png|180px|thumb|Второй проход]]&lt;br /&gt;
 |[[Файл:heap5.png|180px|thumb|Третий проход]]&lt;br /&gt;
 |[[Файл:heap6.png|180px|thumb|Четвертый проход]]&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Пусть дана последовательность из &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;3, 2, 4, 1, 5&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;background-color:#CCC;margin:0.5px&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Массив&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 5 3 4 1 2&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из исходного массива &lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 3 4 1 '''5'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и последний элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''4''' 3 2 1 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых четырех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' 3 2 '''4''' 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и четвертый элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''3''' 1 2 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых трех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Третий проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 '''3''' 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и третий элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из двух элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' '''2''' 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и второй элементы  &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 1 2 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Массив отсортирован&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки == &lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%9F%D0%B8%D1%80%D0%B0%D0%BC%D0%B8%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0 Пирамидальная сортировка - Википедия]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Heapsort Heapsort - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
*''Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К.'' Алгоритмы: построение и анализ, 2-е издание. М.: Издательский дом &amp;quot;Вильямс&amp;quot;, 2005. ISBN 5-8459-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap6.png&amp;diff=24743</id>
		<title>Файл:Heap6.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap6.png&amp;diff=24743"/>
				<updated>2012-06-10T13:30:08Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap5.png&amp;diff=24742</id>
		<title>Файл:Heap5.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap5.png&amp;diff=24742"/>
				<updated>2012-06-10T13:28:51Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap4.png&amp;diff=24741</id>
		<title>Файл:Heap4.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap4.png&amp;diff=24741"/>
				<updated>2012-06-10T13:27:03Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24740</id>
		<title>Файл:Heap3.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap3.png&amp;diff=24740"/>
				<updated>2012-06-10T13:25:38Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap2.png&amp;diff=24737</id>
		<title>Файл:Heap2.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap2.png&amp;diff=24737"/>
				<updated>2012-06-10T13:23:15Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap1.png&amp;diff=24735</id>
		<title>Файл:Heap1.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:Heap1.png&amp;diff=24735"/>
				<updated>2012-06-10T13:20:29Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24731</id>
		<title>Список</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24731"/>
				<updated>2012-06-10T13:02:34Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' - структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Односвязный список ==&lt;br /&gt;
Простейшая реализация списка. В узлах хранятся данные и указатель на следующий элемент в списке.&lt;br /&gt;
[[Файл:simpleSpisok.png|center|400px]]&lt;br /&gt;
==Двусвязный список ==&lt;br /&gt;
Также хранится указатель на предыдущий элемент списка, благодаря чему становится проще удалять и переставлять элементы.&lt;br /&gt;
[[Файл:twiceSpisok.png|center|400px]]&lt;br /&gt;
===XOR-связный список ===&lt;br /&gt;
В некоторых случаях использование двусвязного списка в явном виде является нецелесообразным. В целях экономии памяти можно хранить только результат выполнения операции Xor над адресами предыдущего и следующего элементов списка. Таким образом, зная адрес предыдущего элемента, мы можем вычислить адрес следующего элемента.&lt;br /&gt;
&lt;br /&gt;
==Циклический список==&lt;br /&gt;
Первый элемент является следующим для последнего элемента списка.&lt;br /&gt;
[[Файл:circleSpisok.png|center|450px]]&lt;br /&gt;
==Операции на списке==&lt;br /&gt;
Рассмотрим базовые операции на примере односвязного списка.&lt;br /&gt;
===Вставка===&lt;br /&gt;
Очевиден случай, когда необходимо добавить элемент (&amp;lt;tex&amp;gt;newHead&amp;lt;/tex&amp;gt;) в голову списка. Установим в этом элементе ссылку на старую голову, и обновим указатель на голову.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insert(newHead)&lt;br /&gt;
    newHead.next = head;&lt;br /&gt;
    head = newHead; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:insertHead.png|center|550px]]&lt;br /&gt;
Если же на нужно вставить элемент (&amp;lt;tex&amp;gt;thatElement&amp;lt;/tex&amp;gt;) в определенную позицию после какого-то другого элемента (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;), то просто изменим соответствующие ссылки.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next; &lt;br /&gt;
    thisElement.next = thatElement;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&gt;
===Поиск===&lt;br /&gt;
Для того, чтобы найти элемент по значению (&amp;lt;tex&amp;gt;value&amp;lt;/tex&amp;gt;), будем двигаться по списку от головы до конца и сравнивать значение в элементах с искомым. Если элемента в списке нет, то возвращаем &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Search(value)&lt;br /&gt;
    node = head;&lt;br /&gt;
    while node != NULL and value != node.value&lt;br /&gt;
        node = node.next;&lt;br /&gt;
    return node;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка - переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeHead()&lt;br /&gt;
    if head != NULL&lt;br /&gt;
        tmp = head;&lt;br /&gt;
        head = head.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeAfter(thisElement)&lt;br /&gt;
    if thisElement.next != NULL&lt;br /&gt;
        tmp = thisElement.next;&lt;br /&gt;
        thisElement.next = thisElement.next.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
==См.также==&lt;br /&gt;
[[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
==Ссылки ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Linked_list Linked list - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0) Список - Википедия]&lt;br /&gt;
&lt;br /&gt;
==Литература ==&lt;br /&gt;
* Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 11.2&lt;br /&gt;
* Д. Кнут: Искусство программирования том 1 глава 2.2&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24693</id>
		<title>Список</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24693"/>
				<updated>2012-06-10T10:01:30Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' - структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Односвязный список ==&lt;br /&gt;
Простейшая реализация списка. В узлах хранятся данные и указатель на следующий элемент в списке.&lt;br /&gt;
[[Файл:simpleSpisok.png|center|400px]]&lt;br /&gt;
==Двусвязный список ==&lt;br /&gt;
Также хранится указатель на предыдущий элемент списка, благодаря чему становится проще удалять и переставлять элементы.&lt;br /&gt;
[[Файл:twiceSpisok.png|center|400px]]&lt;br /&gt;
===XOR-связный список ===&lt;br /&gt;
В некоторых случаях использование двусвязного списка в явном виде является нецелесообразным. В целях экономии памяти можно хранить только результат выполнения операции Xor над адресами предыдущего и следующего элементов списка. Таким образом, зная адрес предыдущего элемента, мы можем вычислить адрес следующего элемента.&lt;br /&gt;
&lt;br /&gt;
==Циклический список==&lt;br /&gt;
Первый элемент является следующим для последнего элемента списка.&lt;br /&gt;
[[Файл:circleSpisok.png|center|450px]]&lt;br /&gt;
==Операции на списке==&lt;br /&gt;
Рассмотрим базовые операции на примере односвязного списка.&lt;br /&gt;
===Вставка===&lt;br /&gt;
Очевиден случай, когда необходимо добавить элемент (&amp;lt;tex&amp;gt;newHead&amp;lt;/tex&amp;gt;) в голову списка. Установим в этом элементе ссылку на старую голову, и обновим указатель на голову.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insert(newHead)&lt;br /&gt;
    newHead.next = head;&lt;br /&gt;
    head = newHead; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:insertHead.png|center|550px]]&lt;br /&gt;
Если же на нужно вставить элемент (&amp;lt;tex&amp;gt;thatElement&amp;lt;/tex&amp;gt;) в определенную позицию после какого-то другого элемента (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;), то просто изменим соответствующие ссылки.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next; &lt;br /&gt;
    thisElement.next = thatElement;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&gt;
===Поиск===&lt;br /&gt;
Для того, чтобы найти элемент по значению (&amp;lt;tex&amp;gt;value&amp;lt;/tex&amp;gt;), будем двигаться по списку от головы до конца и сравнивать значение в элементах с искомым. Если элемента в списке нет, то возвращаем &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Search(value)&lt;br /&gt;
    node = head;&lt;br /&gt;
    while node != NULL and value != node.value&lt;br /&gt;
        node = node.next;&lt;br /&gt;
    return node;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка - переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeHead()//удаление головы&lt;br /&gt;
    if head != NULL&lt;br /&gt;
        tmp = head;&lt;br /&gt;
        head = head.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeAfter(thisElement)&lt;br /&gt;
    if thisElement.next != NULL&lt;br /&gt;
        tmp = thisElement.next;&lt;br /&gt;
        thisElement.next = thisElement.next.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
==См.также==&lt;br /&gt;
[[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
==Ссылки ==&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Linked_list Linked list - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
* [http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0) Список - Википедия]&lt;br /&gt;
&lt;br /&gt;
==Литература ==&lt;br /&gt;
* Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 11.2&lt;br /&gt;
* Д. Кнут: Искусство программирования том 1 глава 2.2&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TwiceSpisok.png&amp;diff=24692</id>
		<title>Файл:TwiceSpisok.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:TwiceSpisok.png&amp;diff=24692"/>
				<updated>2012-06-10T09:58:14Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:RemoveAfter.png&amp;diff=24691</id>
		<title>Файл:RemoveAfter.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:RemoveAfter.png&amp;diff=24691"/>
				<updated>2012-06-10T09:44:33Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:RemoveHead.png&amp;diff=24690</id>
		<title>Файл:RemoveHead.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:RemoveHead.png&amp;diff=24690"/>
				<updated>2012-06-10T09:38:09Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:InsertAfter.png&amp;diff=24689</id>
		<title>Файл:InsertAfter.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:InsertAfter.png&amp;diff=24689"/>
				<updated>2012-06-10T09:27:52Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24675</id>
		<title>Список</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24675"/>
				<updated>2012-06-10T00:27:54Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' - структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Односвязный список ==&lt;br /&gt;
Простейшая реализация списка. В узлах хранятся данные и указатель на следующий элемент в списке.&lt;br /&gt;
[[Файл:simpleSpisok.png|center|400px]]&lt;br /&gt;
==Двусвязный список ==&lt;br /&gt;
Также хранится указатель на предыдущий элемент списка, благодаря чему становится проще удалять и переставлять элементы.&lt;br /&gt;
[[Файл:Doubly linked list.png|center|400px]]&lt;br /&gt;
===XOR-связный список ===&lt;br /&gt;
В некоторых случаях использование двусвязного списка в явном виде является нецелесообразным. В целях экономии памяти можно хранить только результат выполнения операции Xor над адресами предыдущего и следующего элементов списка. Таким образом, зная адрес предыдущего элемента, мы можем вычислить адрес следующего элемента.&lt;br /&gt;
&lt;br /&gt;
==Циклический список==&lt;br /&gt;
Первый элемент является следующим для последнего элемента списка.&lt;br /&gt;
[[Файл:circleSpisok.png|center|450px]]&lt;br /&gt;
==Операции на списке==&lt;br /&gt;
Рассмотрим базовые операции на примере односвязного списка.&lt;br /&gt;
===Вставка===&lt;br /&gt;
Очевиден случай, когда необходимо добавить элемент (&amp;lt;tex&amp;gt;newHead&amp;lt;/tex&amp;gt;) в голову списка. Установим в этом элементе ссылку на старую голову, и обновим указатель на голову.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insert(newHead)&lt;br /&gt;
    newHead.next = head;&lt;br /&gt;
    head = newHead; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
[[Файл:insertHead.png|center|550px]]&lt;br /&gt;
Если же на нужно вставить элемент (&amp;lt;tex&amp;gt;thatElement&amp;lt;/tex&amp;gt;) в определенную позицию после какого-то другого элемента (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;), то просто изменим соответствующие ссылки.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next; &lt;br /&gt;
    thisElement.next = thatElement;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Поиск===&lt;br /&gt;
Для того, чтобы найти элемент по значению (&amp;lt;tex&amp;gt;value&amp;lt;/tex&amp;gt;), будем двигаться по списку от головы до конца и сравнивать значение в элементах с искомым. Если элемента в списке нет, то возвращаем &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Search(value)&lt;br /&gt;
    node = head;&lt;br /&gt;
    while node != NULL and value != node.value&lt;br /&gt;
        node = node.next;&lt;br /&gt;
    return node;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка - переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeHead()//удаление головы&lt;br /&gt;
    if head != NULL&lt;br /&gt;
        tmp = head;&lt;br /&gt;
        head = head.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeAfter(thisElement)&lt;br /&gt;
    if thisElement.next != NULL&lt;br /&gt;
        tmp = thisElement.next;&lt;br /&gt;
        thisElement.next = thisElement.next.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==См.также==&lt;br /&gt;
[[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
==Ссылки ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Linked_list Linked list]&lt;br /&gt;
&lt;br /&gt;
==Литература ==&lt;br /&gt;
* Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 11.2&lt;br /&gt;
* Д. Кнут: Искусство программирования том 1 глава 2.2&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:CircleSpisok.png&amp;diff=24674</id>
		<title>Файл:CircleSpisok.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:CircleSpisok.png&amp;diff=24674"/>
				<updated>2012-06-10T00:26:45Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:SimpleSpisok.png&amp;diff=24673</id>
		<title>Файл:SimpleSpisok.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:SimpleSpisok.png&amp;diff=24673"/>
				<updated>2012-06-10T00:22:34Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:InsertHead.png&amp;diff=24672</id>
		<title>Файл:InsertHead.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:InsertHead.png&amp;diff=24672"/>
				<updated>2012-06-10T00:16:55Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE_%D0%BD%D0%B5%D1%8F%D0%B2%D0%BD%D0%BE%D0%BC%D1%83_%D0%BA%D0%BB%D1%8E%D1%87%D1%83&amp;diff=24671</id>
		<title>Декартово дерево по неявному ключу</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE_%D0%BD%D0%B5%D1%8F%D0%B2%D0%BD%D0%BE%D0%BC%D1%83_%D0%BA%D0%BB%D1%8E%D1%87%D1%83&amp;diff=24671"/>
				<updated>2012-06-10T00:02:12Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Основная идея==&lt;br /&gt;
Возьмем структуру данных [[Саморасширяющийся массив|вектор]]. В её стандартной реализации мы умеем добавлять элемент в конец вектора, узнавать значение элемента, стоящего на определенной позиции, изменять элемент по номеру и удалять последний элемент. Предположим, что нам необходима структура данных с вышеуказанными свойствами, а также с операциями: добавить элемент в любое место (с соответствующим изменением нумерации элементов) и удалить любой элемент (также с соответствующим изменением нумерации). Такая структура существует и называется ''декартово дерево по неявному ключу''.&lt;br /&gt;
===Ключ X===&lt;br /&gt;
Как известно, [[декартово дерево]] {{---}} это структура данных, объединяющая в себе бинарное дерево поиска и бинарную кучу. При реализации же декартова дерева по неявному ключу модифицируем эту структуру. А именно, оставим в нем только приоритет &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt;, а вместо ключа &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; будем использовать следующую величину: '''количество элементов в нашей структуре, находящихся левее нашего элемента'''. Иначе говоря, будем считать ключом порядковый номер нашего элемента в дереве, уменьшенный на единицу. &lt;br /&gt;
&lt;br /&gt;
Заметим, что при этом сохранится структура [[Дерево_поиска,_наивная_реализация|двоичного дерева поиска]] по этому ключу (то есть модифицированное декартово дерево так и останется декартовым деревом). Однако, с этим подходом появляется проблема: операции добавления и удаления элемента могут поменять нумерацию, и при наивной реализации на изменение всех ключей потребуется &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов в дереве.&lt;br /&gt;
&lt;br /&gt;
===Вспомогательная величина С===&lt;br /&gt;
Решается эта проблема довольно просто. Основная идея заключается в том, что такой ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; сам по себе нигде не хранится. Вместо него будем хранить вспомогательную величину &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;: '''количество вершин в поддереве нашей вершины''' (в поддерево включается и сама вершина). Обратим внимание, что все операции с обычным декартовым деревом делались сверху. Также заметим, что если по пути до некой вершины просуммировать все такие величины в левых поддеревьях, в которые мы не пошли, увеличенные на единицу, то придя в саму вершину и добавив к этой величине количество элементов в её левом поддереве, мы получим как раз ее ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:DDpoNK.png|Пример описанного дерева с демонстрацией определения ключа &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Операции, поддерживающие структуру декартова дерева==&lt;br /&gt;
Структура обычного декартова дерева поддерживается с помощью двух операций: &amp;lt;tex&amp;gt;split&amp;lt;/tex&amp;gt; {{---}} разбиение одного декартова дерева  на два таких, что в одном ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; меньше, чем заданное значение, а в другом {{---}} больше, и &amp;lt;tex&amp;gt;merge&amp;lt;/tex&amp;gt; {{---}} слияние двух деревьев, в одном из которых все ключи &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; меньше, чем во втором. С учетом отличий декартова дерева по неявному ключу от обычного, операции теперь будут описываться так: &amp;lt;tex&amp;gt;split(root, t)&amp;lt;/tex&amp;gt; {{---}} разбиение дерева на два так, что в левом окажется ровно &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; вершин, и &amp;lt;tex&amp;gt;merge(root1, root2)&amp;lt;/tex&amp;gt; {{---}} слияние двух любых деревьев, соответственно.&lt;br /&gt;
&lt;br /&gt;
===Split===&lt;br /&gt;
Пусть процедура &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; запущена в корне дерева с требованием отрезать от дерева &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; вершин. Также известно, что в левом поддереве вершины находится &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; вершин, а в правом &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. Рассмотрим все возможные случаи: &lt;br /&gt;
* &amp;lt;tex&amp;gt;l = t&amp;lt;/tex&amp;gt;. В этом случае процедура &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; должна просто пометить, что у корня больше нет левого сына, и вернуть его бывшего левого сына в качестве левой части ответа, а сам корень {{---}} в качестве правой. &lt;br /&gt;
* Случай (&amp;lt;tex&amp;gt;t = l + 1&amp;lt;/tex&amp;gt;) рассматривается аналогично предыдущему. &lt;br /&gt;
* &amp;lt;tex&amp;gt;t &amp;lt; l&amp;lt;/tex&amp;gt;. В этом случае нужно рекурсивно запустить процедуру &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; от левого сына с тем же параметром &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и левая часть сына станет левой частью ответа нашей процедуры, а правая часть сына станет левым сыном корня, после чего корень станет правой частью ответа. &lt;br /&gt;
* Случай &amp;lt;tex&amp;gt;t &amp;gt; l + 1&amp;lt;/tex&amp;gt; рассматривается аналогично предыдущему, с той лишь разницей, что от правого сына отрезается &amp;lt;tex&amp;gt;t - l - 1&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
&lt;br /&gt;
===Merge===&lt;br /&gt;
Посмотрим любую из [[Декартово дерево#Операция merge|реализаций]] процедуры &amp;lt;tex&amp;gt;Merge&amp;lt;/tex&amp;gt;. Заметим, что в ней программа ни разу не обращается к ключу &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. Поэтому реализация процедуры &amp;lt;tex&amp;gt;Merge&amp;lt;/tex&amp;gt; для декартова дерева по неявному ключу вообще не будет отличаться от реализации той же процедуры в обычном декартовом дереве.&lt;br /&gt;
&lt;br /&gt;
===Поддержание корректности значений C===&lt;br /&gt;
Единственное действие, обеспечивающее корректность этих значений заключается в том, что после любого действия с детьми вершины нужно записать в ее поле &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; сумму этих значений в ее новых детях, увеличенную на единицу.&lt;br /&gt;
&lt;br /&gt;
==Применение описанного дерева==&lt;br /&gt;
Таким образом, описана структура, от которой можно отрезать слева часть произвольной длины и слить две любые части в одну в нужном порядке. Теперь мы имеем возможность:&lt;br /&gt;
* вставить элемент в любое место (отрежем нужное количество элементов слева, сольем левое дерево с деревом из одного добавленного элемента и результат {{---}} с правым деревом);&lt;br /&gt;
* переставить любой кусок массива куда угодно (сделаем нужные разрезы и слияния в правильном порядке);&lt;br /&gt;
* совершать групповые операции с элементами. Вспомним реализацию таких операций в дереве отрезков и поймем, что ничего не помешает нам сделать то же самое с описанным деревом. В групповые операции включается, естественно, и взятие функции от отрезка.&lt;br /&gt;
* сделав на одном исходном массиве два дерева из элементов разной четности, можно решить задачу про смену мест четных и нечетных на отрезке.&lt;br /&gt;
* с помощью декартова дерева по неявному ключу можно реализовать такую структуру как [http://en.wikipedia.org/wiki/Rope_(computer_science) - Rope]&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
* [http://habrahabr.ru/post/102364/ Habrahabr - Декартово дерево по неявному ключу]&lt;br /&gt;
* [http://e-maxx.ru/algo/treap#7 E-maxx - Неявные декартовы деревья]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Деревья поиска]]&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24670</id>
		<title>Файл:DDpoNK.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24670"/>
				<updated>2012-06-09T23:59:00Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:DDpoNK.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24669</id>
		<title>Список</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24669"/>
				<updated>2012-06-09T23:56:05Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' - структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Односвязный список ==&lt;br /&gt;
Простейшая реализация списка. В узлах хранятся данные и указатель на следующий элемент в списке.&lt;br /&gt;
[[Файл:Single linked list-1-.png|center|400px]]&lt;br /&gt;
==Двусвязный список ==&lt;br /&gt;
Также хранится указатель на предыдущий элемент списка, благодаря чему становится проще удалять и переставлять элементы.&lt;br /&gt;
[[Файл:Doubly linked list.png|center|400px]]&lt;br /&gt;
===XOR-связный список ===&lt;br /&gt;
В некоторых случаях использование двусвязного списка в явном виде является нецелесообразным. В целях экономии памяти можно хранить только результат выполнения операции Xor над адресами предыдущего и следующего элементов списка. Таким образом, зная адрес предыдущего элемента, мы можем вычислить адрес следующего элемента.&lt;br /&gt;
&lt;br /&gt;
==Циклический список==&lt;br /&gt;
Первый элемент является следующим для последнего элемента списка.&lt;br /&gt;
[[Файл:Circurlar linked list.png (872×241).png|center|400px]]&lt;br /&gt;
==Операции на списке==&lt;br /&gt;
Рассмотрим базовые операции на примере односвязного списка.&lt;br /&gt;
===Вставка===&lt;br /&gt;
Очевиден случай, когда необходимо добавить элемент (&amp;lt;tex&amp;gt;newHead&amp;lt;/tex&amp;gt;) в голову списка. Установим в этом элементе ссылку на старую голову, и обновим указатель на голову.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insert(newHead)&lt;br /&gt;
    newHead.next = head;&lt;br /&gt;
    head = newHead; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Если же на нужно вставить элемент (&amp;lt;tex&amp;gt;thatElement&amp;lt;/tex&amp;gt;) в определенную позицию после какого-то другого элемента (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;), то просто изменим соответствующие ссылки.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next; &lt;br /&gt;
    thisElement.next = thatElement;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Поиск===&lt;br /&gt;
Для того, чтобы найти элемент по значению (&amp;lt;tex&amp;gt;value&amp;lt;/tex&amp;gt;), будем двигаться по списку от головы до конца и сравнивать значение в элементах с искомым. Если элемента в списке нет, то возвращаем &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Search(value)&lt;br /&gt;
    node = head;&lt;br /&gt;
    while node != NULL and value != node.value&lt;br /&gt;
        node = node.next;&lt;br /&gt;
    return node;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка - переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeHead()//удаление головы&lt;br /&gt;
    if head != NULL&lt;br /&gt;
        tmp = head;&lt;br /&gt;
        head = head.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeAfter(thisElement)&lt;br /&gt;
    if thisElement.next != NULL&lt;br /&gt;
        tmp = thisElement.next;&lt;br /&gt;
        thisElement.next = thisElement.next.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==См.также==&lt;br /&gt;
[[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
==Ссылки ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Linked_list Linked list]&lt;br /&gt;
&lt;br /&gt;
==Литература ==&lt;br /&gt;
* Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 11.2&lt;br /&gt;
* Д. Кнут: Искусство программирования том 1 глава 2.2&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24446</id>
		<title>Список</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA&amp;diff=24446"/>
				<updated>2012-06-08T17:35:29Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' - структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
==Односвязный список ==&lt;br /&gt;
Простейшая реализация списка. В узлах хранятся данные и указатель на следующий элемент в списке.&lt;br /&gt;
[[Файл:Single linked list-1-.png|center|400px]]&lt;br /&gt;
==Двусвязный список ==&lt;br /&gt;
Также хранится указатель на предыдущий элемент списка, благодаря чему становится проще удалять и переставлять элементы.&lt;br /&gt;
[[Файл:Doubly linked list.png|center|400px]]&lt;br /&gt;
===XOR-связный список ===&lt;br /&gt;
В некоторых случаях использование двусвязного списка в явном виде является нецелесообразным. В целях экономии памяти можно хранить только результат выполнения операции Xor над адресами предыдущего и следующего элементов списка. Таким образом, зная адрес предыдущего элемента, мы можем вычислить адрес следующего элемента.&lt;br /&gt;
&lt;br /&gt;
==Циклический список==&lt;br /&gt;
Первый элемент является следующим для последнего элемента списка.&lt;br /&gt;
[[Файл:Circurlar linked list.png (872×241).png|center|400px]]&lt;br /&gt;
==Операции на списке==&lt;br /&gt;
Рассмотрим базовые операции на примере односвязного списка.&lt;br /&gt;
===Вставка===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insert(newHead)// вставка в голову  списка&lt;br /&gt;
    newHead.next = head;&lt;br /&gt;
    head = newHead; &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
insertAfter(thisElement, thatElement)// вставка после this_element&lt;br /&gt;
    thatElement.next = thisElement.next; &lt;br /&gt;
    thisElement.next = thatElement;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Поиск===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Search(value)//ищем элемент, в случае неудачи возвращаем NULL&lt;br /&gt;
    node = head;&lt;br /&gt;
    while (node != NULL) &amp;amp;&amp;amp; (value != node.value)&lt;br /&gt;
        node = node.next;&lt;br /&gt;
    return node;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
===Удаление===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeHead()//удаление головы&lt;br /&gt;
    if head != NULL&lt;br /&gt;
        tmp = head;&lt;br /&gt;
        head = head.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
removeAfter(thisElement)&lt;br /&gt;
    if (thisElement != NULL) &amp;amp;&amp;amp; (thisElement.next != NULL)&lt;br /&gt;
        tmp = thisElement.next;&lt;br /&gt;
        thisElement.next = thisElement.next.next;&lt;br /&gt;
        delete tmp;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
==См.также==&lt;br /&gt;
[[Массив с увеличением/уменьшением размера]]&lt;br /&gt;
==Ссылки ==&lt;br /&gt;
[http://en.wikipedia.org/wiki/Linked_list Linked list]&lt;br /&gt;
&lt;br /&gt;
==Литература ==&lt;br /&gt;
* Т. Кормен, Ч. Лейзерсон, Р. Ривест: Алгоритмы: построение и анализ глава 11.2&lt;br /&gt;
* Д. Кнут: Искусство программирования том 1 глава 2.2&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE_%D0%BD%D0%B5%D1%8F%D0%B2%D0%BD%D0%BE%D0%BC%D1%83_%D0%BA%D0%BB%D1%8E%D1%87%D1%83&amp;diff=24384</id>
		<title>Декартово дерево по неявному ключу</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B5%D0%BA%D0%B0%D1%80%D1%82%D0%BE%D0%B2%D0%BE_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_%D0%BF%D0%BE_%D0%BD%D0%B5%D1%8F%D0%B2%D0%BD%D0%BE%D0%BC%D1%83_%D0%BA%D0%BB%D1%8E%D1%87%D1%83&amp;diff=24384"/>
				<updated>2012-06-07T18:03:01Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Основная идея==&lt;br /&gt;
Возьмем структуру данных [[Саморасширяющийся массив|вектор]]. В её стандартной реализации мы умеем добавлять элемент в конец вектора, узнавать значение элемента, стоящего на определенной позиции, изменять элемент по номеру и удалять последний элемент. Предположим, что нам необходима структура данных с вышеуказанными свойствами, а также с операциями: добавить элемент в любое место (с соответствующим изменением нумерации элементов) и удалить любой элемент (также с соответствующим изменением нумерации). Такая структура существует и называется ''декартово дерево по неявному ключу''.&lt;br /&gt;
===Ключ X===&lt;br /&gt;
Как известно, [[декартово дерево]] {{---}} это структура данных, объединяющая в себе бинарное дерево поиска и бинарную кучу. При реализации же декартова дерева по неявному ключу модифицируем эту структуру. А именно, оставим в нем только приоритет &amp;lt;tex&amp;gt;Y&amp;lt;/tex&amp;gt;, а вместо ключа &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; будем использовать следующую величину: '''количество элементов в нашей структуре, находящихся левее нашего элемента'''. Иначе говоря, будем считать ключом порядковый номер нашего элемента в дереве, уменьшенный на единицу. &lt;br /&gt;
&lt;br /&gt;
Заметим, что при этом сохранится структура [[Дерево_поиска,_наивная_реализация|двоичного дерева поиска]] по этому ключу (то есть модифицированное декартово дерево так и останется декартовым деревом). Однако, с этим подходом появляется проблема: операции добавления и удаления элемента могут поменять нумерацию, и при наивной реализации на изменение всех ключей потребуется &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; времени, где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов в дереве.&lt;br /&gt;
&lt;br /&gt;
===Вспомогательная величина С===&lt;br /&gt;
Решается эта проблема довольно просто. Основная идея заключается в том, что такой ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; сам по себе нигде не хранится. Вместо него будем хранить вспомогательную величину &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt;: '''количество вершин в поддереве нашей вершины''' (в поддерево включается и сама вершина). Обратим внимание, что все операции с обычным декартовым деревом делались сверху. Также заметим, что если по пути до некой вершины просуммировать все такие величины в левых поддеревьях, в которые мы не пошли, увеличенные на единицу, то придя в саму вершину и добавив к этой величине количество элементов в её левом поддереве, мы получим как раз ее ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Файл:DDpoNK.png|Пример описанного дерева с демонстрацией определения ключа &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Операции, поддерживающие структуру декартова дерева==&lt;br /&gt;
Структура обычного декартова дерева поддерживается с помощью двух операций: &amp;lt;tex&amp;gt;split&amp;lt;/tex&amp;gt; {{---}} разбиение одного декартова дерева  на два таких, что в одном ключ &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; меньше, чем заданное значение, а в другом {{---}} больше, и &amp;lt;tex&amp;gt;merge&amp;lt;/tex&amp;gt; {{---}} слияние двух деревьев, в одном из которых все ключи &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; меньше, чем во втором. С учетом отличий декартова дерева по неявному ключу от обычного, операции теперь будут описываться так: &amp;lt;tex&amp;gt;split(root, t)&amp;lt;/tex&amp;gt; {{---}} разбиение дерева на два так, что в левом окажется ровно &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; вершин, и &amp;lt;tex&amp;gt;merge(root1, root2)&amp;lt;/tex&amp;gt; {{---}} слияние двух любых деревьев, соответственно.&lt;br /&gt;
&lt;br /&gt;
===Split===&lt;br /&gt;
Пусть процедура &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; запущена в корне дерева с требованием отрезать от дерева &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt; вершин. Также известно, что в левом поддереве вершины находится &amp;lt;tex&amp;gt;l&amp;lt;/tex&amp;gt; вершин, а в правом &amp;lt;tex&amp;gt;r&amp;lt;/tex&amp;gt;. Рассмотрим все возможные случаи: &lt;br /&gt;
* &amp;lt;tex&amp;gt;l = t&amp;lt;/tex&amp;gt;. В этом случае процедура &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; должна просто пометить, что у корня больше нет левого сына, и вернуть его бывшего левого сына в качестве левой части ответа, а сам корень {{---}} в качестве правой. &lt;br /&gt;
* Случай (&amp;lt;tex&amp;gt;t = l + 1&amp;lt;/tex&amp;gt;) рассматривается аналогично предыдущему. &lt;br /&gt;
* &amp;lt;tex&amp;gt;t &amp;lt; l&amp;lt;/tex&amp;gt;. В этом случае нужно рекурсивно запустить процедуру &amp;lt;tex&amp;gt;Split&amp;lt;/tex&amp;gt; от левого сына с тем же параметром &amp;lt;tex&amp;gt;t&amp;lt;/tex&amp;gt;, и левая часть сына станет левой частью ответа нашей процедуры, а правая часть сына станет левым сыном корня, после чего корень станет правой частью ответа. &lt;br /&gt;
* Случай &amp;lt;tex&amp;gt;t &amp;gt; l + 1&amp;lt;/tex&amp;gt; рассматривается аналогично предыдущему, с той лишь разницей, что от правого сына отрезается &amp;lt;tex&amp;gt;t - l - 1&amp;lt;/tex&amp;gt; вершин.&lt;br /&gt;
&lt;br /&gt;
===Merge===&lt;br /&gt;
Посмотрим любую из [[Декартово дерево#Операция merge|реализаций]] процедуры &amp;lt;tex&amp;gt;Merge&amp;lt;/tex&amp;gt;. Заметим, что в ней программа ни разу не обращается к ключу &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;. Поэтому реализация процедуры &amp;lt;tex&amp;gt;Merge&amp;lt;/tex&amp;gt; для декартова дерева по неявному ключу вообще не будет отличаться от реализации той же процедуры в обычном декартовом дереве.&lt;br /&gt;
&lt;br /&gt;
===Поддержание корректности значений C===&lt;br /&gt;
Единственное действие, обеспечивающее корректность этих значений заключается в том, что после любого действия с детьми вершины нужно записать в ее поле &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; сумму этих значений в ее новых детях, увеличенную на единицу.&lt;br /&gt;
&lt;br /&gt;
==Применение описанного дерева==&lt;br /&gt;
Таким образом, описана структура, от которой можно отрезать слева часть произвольной длины и слить две любые части в одну в нужном порядке. Теперь мы имеем возможность:&lt;br /&gt;
* вставить элемент в любое место (отрежем нужное количество элементов слева, сольем левое дерево с деревом из одного добавленного элемента и результат {{---}} с правым деревом);&lt;br /&gt;
* переставить любой кусок массива куда угодно (сделаем нужные разрезы и слияния в правильном порядке);&lt;br /&gt;
* совершать групповые операции с элементами. Вспомним реализацию таких операций в дереве отрезков и поймем, что ничего не помешает нам сделать то же самое с описанным деревом. В групповые операции включается, естественно, и взятие функции от отрезка.&lt;br /&gt;
* сделав на одном исходном массиве два дерева из элементов разной четности, можно решить задачу про смену мест четных и нечетных на отрезке.&lt;br /&gt;
&lt;br /&gt;
==Ссылки==&lt;br /&gt;
* [http://habrahabr.ru/post/102364/ Habrahabr - Декартово дерево по неявному ключу]&lt;br /&gt;
* [http://e-maxx.ru/algo/treap#7 E-maxx - Неявные декартовы деревья]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Деревья поиска]]&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24382</id>
		<title>Файл:DDpoNK.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24382"/>
				<updated>2012-06-07T17:49:48Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: загружена новая версия «Файл:DDpoNK.png»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24381</id>
		<title>Файл:DDpoNK.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:DDpoNK.png&amp;diff=24381"/>
				<updated>2012-06-07T17:44:44Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=23590</id>
		<title>Сортировка кучей</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=23590"/>
				<updated>2012-06-03T20:51:50Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка кучей''', '''пирамидальная сортировка''' (англ. '''Heapsort''') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это нестабильный алгоритм сортировки с временем работы &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов для сортировки, и использующий &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; дополнительной памяти.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Необходимо отсортировать массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, размером &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Построим на базе этого массива за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, он встанет на свое место. Далее вызовем процедуру '''sift_down(0)''', предварительно уменьшив &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Она за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; просеет &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; на нужное место и сформирует новую кучу (так как мы уменьшили ее размер, то куча располагается с &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;A[n - 2]&amp;lt;/tex&amp;gt;, а элемент &amp;lt;tex&amp;gt;A[n-1]&amp;lt;/tex&amp;gt; находится на своем месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, а с &amp;lt;tex&amp;gt;A[n-2]&amp;lt;/tex&amp;gt;. Делая аналогичные действия, пока &amp;lt;tex&amp;gt;heap\_size&amp;lt;/tex&amp;gt; не станет равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.&lt;br /&gt;
&lt;br /&gt;
== Реализация ==&lt;br /&gt;
&amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; {{---}} массив, который необходимо отсортировать; &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов в нем; '''build_heap(A)''' - процедура, которая строит из передаваемого массива невозрастающую кучу в этом же массиве; '''sift_down(A, i, len)''' {{---}} процедура, которая просеивает вниз элемент &amp;lt;tex&amp;gt;A[i]&amp;lt;/tex&amp;gt; в куче из &amp;lt;tex&amp;gt;len&amp;lt;/tex&amp;gt; элементов, находящихся в начале массива &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
heapsort(A)&lt;br /&gt;
  build_heap(A);&lt;br /&gt;
  heap_size = A.size;&lt;br /&gt;
  for i = 0 to n - 2&lt;br /&gt;
    swap(A[0], A[n - 1 - i]);&lt;br /&gt;
    heap_size--;&lt;br /&gt;
    sift_down(A, 0, heap_size);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Сложность ==&lt;br /&gt;
Операция '''sift_down''' работает за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. Всего цикл выполняется &amp;lt;tex&amp;gt;(n - 1)&amp;lt;/tex&amp;gt; раз. Таким образом сложность сортировки кучей является &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
{|align=&amp;quot;right&amp;quot;&lt;br /&gt;
 |-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |[[Файл:Документ1.png|120px|thumb|Строим кучу]]&lt;br /&gt;
 |[[Файл:Документ2.png|120px|thumb|Первый проход]]&lt;br /&gt;
 |[[Файл:Документ3.png|120px|thumb|Строим новую кучу]]&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Файл:Документ4.png|120px|thumb|Второй проход]]&lt;br /&gt;
 |[[Файл:Документ5.png|120px|thumb|Третий проход]]&lt;br /&gt;
 |[[Файл:Документ6.png|120px|thumb|Четвертый проход]]&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Пусть дана последовательность из &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;3, 2, 4, 1, 5&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;background-color:#CCC;margin:0.5px&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Массив&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 5 3 4 1 2&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из исходного массива &lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 3 4 1 '''5'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и последний элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''4''' 3 2 1 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых четырех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' 3 2 '''4''' 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и четвертый элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''3''' 1 2 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых трех элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Третий проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 '''3''' 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и третий элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из двух элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' '''2''' 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и второй элементы  &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 1 2 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Массив отсортирован&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Ссылки == &lt;br /&gt;
*[http://ru.wikipedia.org/wiki/%D0%9F%D0%B8%D1%80%D0%B0%D0%BC%D0%B8%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0 Пирамидальная сортировка - Википедия]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Heapsort Heapsort - Wikipedia]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
*''Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К.'' Алгоритмы: построение и анализ, 2-е издание. М.: Издательский дом &amp;quot;Вильямс&amp;quot;, 2005. ISBN 5-8459-0857-4&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%826.png&amp;diff=23584</id>
		<title>Файл:Документ6.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%826.png&amp;diff=23584"/>
				<updated>2012-06-03T20:36:33Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%825.png&amp;diff=23583</id>
		<title>Файл:Документ5.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%825.png&amp;diff=23583"/>
				<updated>2012-06-03T20:33:53Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%824.png&amp;diff=23582</id>
		<title>Файл:Документ4.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%824.png&amp;diff=23582"/>
				<updated>2012-06-03T20:27:07Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%823.png&amp;diff=23581</id>
		<title>Файл:Документ3.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%823.png&amp;diff=23581"/>
				<updated>2012-06-03T20:25:06Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%822.png&amp;diff=23579</id>
		<title>Файл:Документ2.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%822.png&amp;diff=23579"/>
				<updated>2012-06-03T19:59:07Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%821.png&amp;diff=23578</id>
		<title>Файл:Документ1.png</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A4%D0%B0%D0%B9%D0%BB:%D0%94%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%821.png&amp;diff=23578"/>
				<updated>2012-06-03T19:56:49Z</updated>
		
		<summary type="html">&lt;p&gt;Zakirzyanov: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zakirzyanov</name></author>	</entry>

	</feed>