<?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=79.134.198.186&amp;*</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=79.134.198.186&amp;*"/>
		<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/79.134.198.186"/>
		<updated>2026-06-11T18:40:58Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40080</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40080"/>
				<updated>2014-09-23T14:39:50Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Часто используемые графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}} &lt;br /&gt;
Данное определение разрешает соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Граф с кратными рёбрами принято называть '''мультиграфом''' (англ. ''multigraph''). Если в мультиграфе присутствуют петли, то такой граф называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены параллельные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному, его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' (англ. ''length'') пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''эйлеровым''' (англ. ''eulerian graph''), если он содержит эйлеров цикл. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Гамильтоновы графы}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''гамильтоновым''' (англ. ''hamiltonian graph''), если он содержит гамильтонов цикл.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Укладка графа на плоскости}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''планарным''' (англ. ''planar graph''), если он обладает укладкой на плоскости. '''Плоским''' (англ. ''plane graph'', ''planar embedding of the graph'') называется граф уже уложенный на плоскости.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Лемма о безопасном ребре}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Остовное дерево''' (англ. ''spanning tree'') {{---}} ациклический связный подграф данного связного неориентированного графа, в который входят все его вершины.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Связь степени матрицы смежности и количества путей]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40078</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40078"/>
				<updated>2014-09-23T10:00:49Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Часто используемые графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены параллельные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному, его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' (англ. ''length'') пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Эйлеров цикл, Эйлеров путь, Эйлеровы графы, Эйлеровость орграфов}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''эйлеровым''' (англ. ''eulerian graph''), если он содержит эйлеров цикл. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Гамильтоновы графы}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''гамильтоновым''' (англ. ''hamiltonian graph''), если он содержит гамильтонов цикл.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Укладка графа на плоскости}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''планарным''' (англ. ''planar graph''), если он обладает укладкой на плоскости. '''Плоским''' (англ. ''plane graph'', ''planar embedding of the graph'') называется граф уже уложенный на плоскости.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Остовное дерево''' (англ. ''spanning tree'') {{---}} ациклический связный подграф данного связного неориентированного графа, в который входят все его вершины.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Связь степени матрицы смежности и количества путей]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40077</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40077"/>
				<updated>2014-09-23T09:56:05Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Пути в графах */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены параллельные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному, его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' (англ. ''length'') пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Эйлеров цикл, Эйлеров_путь, Эйлеровы графы, Эйлеровость_орграфов}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''эйлеровым''' (англ. ''eulerian graph''), если он содержит эйлеров цикл. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Гамильтоновы графы}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''гамильтоновым''' (англ. ''hamiltonian graph''), если он содержит гамильтонов цикл.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Укладка графа на плоскости}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''планарным''' (англ. ''planar graph''), если он обладает укладкой на плоскости. '''Плоским''' (англ. ''plane graph'', ''planar embedding of the graph'') называется граф уже уложенный на плоскости.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Остовное дерево''' (англ. ''spanning tree'') {{---}} ациклический связный подграф данного связного неориентированного графа, в который входят все его вершины.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Связь степени матрицы смежности и количества путей]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40076</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40076"/>
				<updated>2014-09-23T09:54:14Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Часто используемые графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены параллельные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному, его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' (англ. ''length'') {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Эйлеров цикл, Эйлеров_путь, Эйлеровы графы, Эйлеровость_орграфов}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''эйлеровым''' (англ. ''eulerian graph''), если он содержит эйлеров цикл. &lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Гамильтоновы графы}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''гамильтоновым''' (англ. ''hamiltonian graph''), если он содержит гамильтонов цикл.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Укладка графа на плоскости}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Граф называется '''планарным''' (англ. ''planar graph''), если он обладает укладкой на плоскости. '''Плоским''' (англ. ''plane graph'', ''planar embedding of the graph'') называется граф уже уложенный на плоскости.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Остовное дерево''' (англ. ''spanning tree'') {{---}} ациклический связный подграф данного связного неориентированного графа, в который входят все его вершины.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==См. также==&lt;br /&gt;
* [[Лемма о рукопожатиях]]&lt;br /&gt;
* [[Матрица смежности графа]]&lt;br /&gt;
* [[Связь степени матрицы смежности и количества путей]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40075</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40075"/>
				<updated>2014-09-23T09:36:51Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Матрица и списки смежности */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены параллельные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному, его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' (англ. ''length'') {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&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;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40074</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40074"/>
				<updated>2014-09-23T08:49:43Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены паралелльные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф '''разрежен''' (англ. ''sparse graph''), &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному), его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i), k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ''ориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в ''неориентированном графе'' называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \bmod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \bmod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' (англ. ''simple path'') {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' (англ. ''length'') {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' (англ. ''complete graph'') {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' (англ. ''tree'') {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' (англ. ''bipartite graph'') {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' (англ. ''regular graph'') {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&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;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
* [[wikipedia:Graph_(mathematics) | Wikipedia {{---}} Graph]]&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40073</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40073"/>
				<updated>2014-09-23T08:16:52Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Неориентированные графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''''Неориентированным графом''''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены паралелльные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф разрежен (англ. ''sparse graph'', &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному), его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i)&amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в неориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \mod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \mod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&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;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40072</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40072"/>
				<updated>2014-09-23T08:14:11Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Ориентированные графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' (англ. ''isomorphic graphs'') {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v, v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Два ребра, имеющие общую концевую вершину, то есть &amp;lt;tex&amp;gt;e_1=(v, u_1)&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e_2=(v, u_2)&amp;lt;/tex&amp;gt;, называются '''смежными''' (англ. ''adjacent''). &lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные'''.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' (англ. ''incidence'') {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt;-графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. &lt;br /&gt;
}}&lt;br /&gt;
Такой граф &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом''' (англ. ''multigraph'').&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
Для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e \mid \operatorname{beg(e)} = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e \mid \operatorname{end(e)} = v_i\}|&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;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены паралелльные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф разрежен (англ. ''sparse graph'', &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному), его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i)&amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в неориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \mod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \mod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&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;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40071</id>
		<title>Основные определения теории графов</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D0%BD%D1%8B%D0%B5_%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D0%B8_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2&amp;diff=40071"/>
				<updated>2014-09-23T07:42:00Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Часто используемые графы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Ориентированные графы==&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' (англ. ''directed graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин (англ. ''vertices''), а &amp;lt;tex&amp;gt; E \subset V \times V &amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Конечным графом''' (англ. ''finite graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется граф, в котором множества &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} конечны. Следует заметить, что большинство рассматриваевых нами графов {{---}} конечны.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' (англ. ''edge'', дугой (англ. ''arc''), линией (англ. ''line'')) ориентированного графа называют упорядоченную пару вершин &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Изоморфные графы''' {{---}} два графа A и B называются изоморфными, если можно установить биекцию между их вершинами и соответствующими им ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
В графе ребро, концы которого совпадают, то есть &amp;lt;tex&amp;gt;e=(v,v)&amp;lt;/tex&amp;gt;, называется &amp;lt;b&amp;gt;петлей&amp;lt;/b&amp;gt; (англ. ''loop'').&lt;br /&gt;
&lt;br /&gt;
Если имеется ребро &amp;lt;tex&amp;gt; (v, u) \in E &amp;lt;/tex&amp;gt;, то говорят:&lt;br /&gt;
* &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''предок''' (англ. ''direct predecessor'') &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt;.&lt;br /&gt;
* &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; {{---}} '''смежные''' (англ. ''adjacent'')&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; u &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;&lt;br /&gt;
* Вершина &amp;lt;tex&amp;gt; v &amp;lt;/tex&amp;gt; '''инцидентна''' ребру &amp;lt;tex&amp;gt; (v, u) &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Инцидентность''' {{---}} понятие, используемое только в отношении ребра и вершины. Две вершины или два ребра не могут быть инцидентны.&lt;br /&gt;
&lt;br /&gt;
Граф с &amp;lt;tex&amp;gt; p &amp;lt;/tex&amp;gt; вершинами и &amp;lt;tex&amp;gt; q &amp;lt;/tex&amp;gt; ребрами называют &amp;lt;tex&amp;gt; (p, q) &amp;lt;/tex&amp;gt; - графом.  &amp;lt;tex&amp;gt; (1, 0) &amp;lt;/tex&amp;gt;-граф называют &amp;lt;b&amp;gt;тривиальным&amp;lt;/b&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Заметим, что по определению ориентированного графа, данному выше, любые две вершины &amp;lt;tex&amp;gt;u,~v&amp;lt;/tex&amp;gt; нельзя соединить более чем одним ребром &amp;lt;tex&amp;gt;(u, v)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Поэтому часто используют другое определение. &lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def1&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется четверка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{beg}, \operatorname{end})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} некоторые множества, а &amp;lt;tex&amp;gt;\operatorname{beg}, \operatorname{end} : E \rightarrow V&amp;lt;/tex&amp;gt;. Такой граф иногда называют '''псевдографом''' (англ. ''pseudograph'').&lt;br /&gt;
}}&lt;br /&gt;
В псевдографе допускается соединять вершины более чем одним ребром. Такие ребра называются '''кратными''' (иначе {{---}} '''параллельные''', англ. ''multi-edge'', ''parallel edge''). Псевдограф без петель принято называть '''мультиграфом'''.&lt;br /&gt;
{|border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=30% align=center&lt;br /&gt;
|[[Файл: Graph_definition_1.png|thumb|210px|center|&amp;lt;font color=#ff2a2a&amp;gt;Красным&amp;lt;/font&amp;gt; выделено кратное ребро (6, 2)&amp;lt;br&amp;gt;&amp;lt;font color=#3771c8&amp;gt;Синим&amp;lt;/font&amp;gt; обозначена петля (6, 6)]]&lt;br /&gt;
|[[Файл: Multi_graph.png|thumb|150px|center|Мультиграф]]&lt;br /&gt;
|[[Файл: Pseudo_graph.png|thumb|150px|center|Псевдограф]]&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Также для ориентированных графов определяют '''полустепень исхода вершины''' (англ. ''outdegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^+v_i = |\{e~|~\operatorname{beg}~e = v_i\}|&amp;lt;/tex&amp;gt; и '''полустепень захода вершины''' (англ. ''indegree'') &amp;lt;tex&amp;gt;\operatorname{deg}^-v_i = |\{e~|~\operatorname{end}~e = v_i\}|&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Стоит отметить, что для ориентированного графа справедлива [[Лемма о рукопожатиях|лемма о рукопожатиях]], связывающая количество ребер с суммой [[Основные определения теории графов#Степень вершины|степеней вершин]].&lt;br /&gt;
&lt;br /&gt;
==Неориентированные графы==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' (англ. ''undirected graph'') &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется пара &amp;lt;tex&amp;gt;G = (V, E)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, а &amp;lt;tex&amp;gt; E \subset \{\{v, u\}: v, u \in V\}&amp;lt;/tex&amp;gt; {{---}} множество рёбер.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Ребром''' в неориентированном графе называют неупорядоченную пару вершин &amp;lt;tex&amp;gt; \{v, u\} \in E &amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
[[Файл: Graph_definition_2.png|thumb|210px|center|Неориентированный граф&amp;lt;br&amp;gt;]]&lt;br /&gt;
Иное определение:&lt;br /&gt;
{{Определение&lt;br /&gt;
|id = def_undirected_graph_2&lt;br /&gt;
|definition =&lt;br /&gt;
'''Неориентированным графом''' &amp;lt;tex&amp;gt;G&amp;lt;/tex&amp;gt; называется тройка &amp;lt;tex&amp;gt;G = (V, E, \operatorname{ends})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;V&amp;lt;/tex&amp;gt; {{---}} множество вершин, &amp;lt;tex&amp;gt;E&amp;lt;/tex&amp;gt; {{---}} множество ребер, а &amp;lt;tex&amp;gt;\operatorname{ends} : E \to \{\{u, v\}, u, v \in V\}&amp;lt;/tex&amp;gt;. Это определение, в отличие от предыдущего, позволяет задавать графы с кратными ребрами.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
'''Степенью''' (англ. ''degree'', ''valency'') вершины &amp;lt;tex&amp;gt;\operatorname{deg} v_i&amp;lt;/tex&amp;gt; в неориентированном графе называют число ребер, инцидентных &amp;lt;tex&amp;gt;v_i&amp;lt;/tex&amp;gt;. Будем считать, что петли добавляют к степени вершины &amp;lt;tex&amp;gt;2&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;
Граф можно представить в виде [[Матрица смежности графа|матрицы смежности]] (англ. ''adjacency matrix''), где &amp;lt;tex&amp;gt;graph[v][u] = true \Leftrightarrow (v, u) \in E&amp;lt;/tex&amp;gt;. Также в ячейке матрицы можно хранить вес ребра или их количество (если в графе разрешены паралелльные ребра).&lt;br /&gt;
Для матрицы смежности существует [[Связь степени матрицы смежности и количества путей|теорема]], позволяющая связать степень матрицы  и количество путей из вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; в вершину &amp;lt;tex&amp;gt;u&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Если граф разрежен (англ. ''sparse graph'', &amp;lt;tex&amp;gt;|E| \ll |V^2|&amp;lt;/tex&amp;gt;, то есть, неформально говоря, в нем не очень много ребер. Формально говорить не получается, потому что везде разреженные графы определяются по-разному), его лучше представить в виде списков смежности, где список для вершины &amp;lt;tex&amp;gt;v&amp;lt;/tex&amp;gt; будет содержать вершины &amp;lt;tex&amp;gt;u: (v, u) \in E&amp;lt;/tex&amp;gt;. Данный способ позволит сэкономить память, так как не придется хранить много нулей.&lt;br /&gt;
&lt;br /&gt;
=== Пути в графах ===&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Путём''' (маршрутом,англ. ''path'') в графе называется последовательность вида &amp;lt;tex&amp;gt;v_0 e_1 v_1 ... e_k v_k&amp;lt;/tex&amp;gt;,  где &amp;lt;tex&amp;gt;e_i \in E,~e_i = (v_{i-1}, v_i)&amp;lt;/tex&amp;gt;; &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; {{---}} '''длина''' пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' (англ. ''closed walk'') в ориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Циклическим путём''' в неориентированном графе называется путь, в котором &amp;lt;tex&amp;gt;v_0 = v_k&amp;lt;/tex&amp;gt;, а так же &amp;lt;tex&amp;gt; e_i \ne e_{(i+1) \mod k}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition =&lt;br /&gt;
'''Цикл''' (англ. ''integral cycle'') {{---}} это [[Отношение эквивалентности#Классы эквивалентности|класс эквивалентности]] циклических путей на отношении эквивалентности таком, что два пути эквивалентны, если &amp;lt;tex&amp;gt; \exists  j \forall i : e_{(i \mod k)} = e'_{(i + j) \mod k}&amp;lt;/tex&amp;gt;; где &amp;lt;tex&amp;gt;e&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;e'&amp;lt;/tex&amp;gt; {{---}} это две последовательности ребер в циклическом пути.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Простой (вершинно-простой) путь''' {{---}} путь, в котором каждая из вершин графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Реберно-простой путь''' {{---}} путь, в котором каждое из ребер графа встречается не более одного раза.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Длина пути''' {{---}} количество [[Основные определения теории графов|рёбер]], входящих в последовательность, задающую этот путь.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Часто используемые графы ==&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Полный граф''' {{---}} граф, в котором каждая пара различных вершин смежна. Полный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами имеет &amp;lt;tex&amp;gt;n(n-1)/2&amp;lt;/tex&amp;gt; рёбер и обозначается &amp;lt;tex&amp;gt;K_n&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{main|Дерево, эквивалентные определения}}&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition='''Дерево''' {{---}} связный ациклический граф.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Двудольный граф''' или '''биграф''' {{---}} граф, множество вершин которого можно разбить на две части таким образом, что каждое ребро графа соединяет какую-то вершину из одной части с какой-то вершиной другой части, то есть не существует ребра, соединяющего две вершины из одной и той же части. Двудольный граф с &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; вершинами в одной доле и &amp;lt;tex&amp;gt;m&amp;lt;/tex&amp;gt; во второй обозначается &amp;lt;tex&amp;gt;K_{n,m}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{Определение&lt;br /&gt;
|definition=&lt;br /&gt;
'''Регулярный граф''' {{---}} граф, степени всех вершин которого равны, то есть каждая вершина имеет одинаковое количество соседей. Регулярный граф с вершинами степени &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; называется &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt;‑регулярным, или регулярным графом степени &amp;lt;tex&amp;gt;k&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;
* Харари Фрэнк '''Теория графов''' = Graph theory/Пер. с англ. и предисл. В. П. Козырева. Под ред. Г.П.Гаврилова. Изд. 2-е. — М.: Едиториал УРСС, 2003. — 296 с. — ISBN 5-354-00301-6&lt;br /&gt;
* Асанов М. О., Баранский В. А., Расин В. В. '''Дискретная математика: графы, матроиды, алгоритмы''' — НИЦ РХД, 2001. — 288 с. — ISBN 5-93972-076-5&lt;br /&gt;
* ''Кормен, Томас Х., Лейзерсон, Чарльз И., Ривест, Рональд Л., Штайн Клиффорд'' '''Алгоритмы: построение и анализ''', 2-е издание. Пер. с англ. — М.:Издательский дом &amp;quot;Вильямс&amp;quot;, 2010. — 1296 с.: ил. — Парал. тит. англ. — ISBN 978-5-8459-0857-5 (рус.)&lt;br /&gt;
* [http://mathworld.wolfram.com/Graph.html Wolfram Mathworld: Graph]&lt;br /&gt;
* [[wikipedia:ru:Граф_(математика) | Википедия {{---}} Граф]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Алгоритмы и структуры данных]]&lt;br /&gt;
[[Категория: Основные определения теории графов]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38856</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=38856"/>
				<updated>2014-06-12T16:21:54Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Поиск длины хвоста в списке с циклом */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(Node thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node search('''int''' 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' removeAfter(Node 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель (черепаха) переходит к следующему элементу списка, а второй указатель (заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' hasCycle(Node head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
Если цикла не существует, то заяц первым дойдет до конца и функция возвратит &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В другом случае, в тот момент, когда и черепаха и заяц находятся в цикле, расстояние между ними будет сокращаться на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (так как &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;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;
Так как для поиска хвоста мы должны знать, что цикл существует, воспользуемся предыдущей функцией и при выходе из неё запомним &amp;quot;момент встречи&amp;quot; зайца и черепахи. Назовем её &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Наивные реализации===&lt;br /&gt;
====Реализация за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;====&lt;br /&gt;
Будем последовательно идти от начала цикла и проверять, лежит ли этот элемент на цикле. На каждой итерации запустим от текущего элемента вперёд указатель. Если он окажется в текущем элементе, прежде чем два раза посетит &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;, то точку окончания (начала) хвоста нашли.&lt;br /&gt;
====Реализация за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;====&lt;br /&gt;
Реализацию, приведенную выше можно улучшить. Для этого воспользуемся бинарным поиском. Сначала проверим голову списка, потом сделаем 2 шага вперёд, потом 4, потом 8 и так далее, пока не окажемся на цикле. Теперь у нас есть две позиции {{---}} на левой границе, где мы в хвосте, и на правой {{---}} в цикле. Сделаем бинарный поиск уже по этому отрезку и таким образом найдём цикл за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Эффективная реализация===&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический (указатель &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка (указатель &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; последнего элемента равен любому другому (не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Достаточно запустить один указатель из &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла. Сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(Node head, Node pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
====Доказательство корректности алгоритма====&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача про обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
Эта рекурсивная функция принимает указатель на голову списка и предыдущий элемент (при запуске указывать &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;), а возвращает указатель на новую голову списка.&lt;br /&gt;
   &lt;br /&gt;
  Node reverse(Node current, Node prev):&lt;br /&gt;
    '''if''' current == ''NULL''&lt;br /&gt;
      '''return''' prev&lt;br /&gt;
    next = current.next&lt;br /&gt;
    current.next = prev&lt;br /&gt;
    '''return''' reverse(next, current)&lt;br /&gt;
&lt;br /&gt;
Алгоритм корректен, поскольку значения элементов в списке не изменяются, а все указатели &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; изменят свое направление, не нарушив связности самого списка. &lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38824</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=38824"/>
				<updated>2014-06-12T15:09:04Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(Node thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node search('''int''' 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' removeAfter(Node 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель (черепаха) переходит к следующему элементу списка, а второй указатель (заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' hasCycle(Node head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
Если цикла не существует, то заяц первым дойдет до конца и функция возвратит &amp;lt;tex&amp;gt;false&amp;lt;/tex&amp;gt;. В другом случае, в тот момент, когда и черепаха и заяц находятся в цикле, расстояние между ними будет сокращаться на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; (так как &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;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;
Так как для поиска хвоста мы должны знать, что цикл существует, воспользуемся предыдущей функцией и при выходе из неё запомним &amp;quot;момент встречи&amp;quot; зайца и черепахи. Назовем её &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Реализация за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;===&lt;br /&gt;
Будем последовательно идти от начала цикла и проверять, лежит ли этот элемент на цикле. На каждой итерации запустим от текущего элемента вперёд указатель. Если он окажется в текущем элементе, прежде чем два раза посетит &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;, то точку окончания (начала) хвоста нашли.&lt;br /&gt;
  '''int''' getTail(Node head, Node pointMeeting):&lt;br /&gt;
    lengthTail = 0&lt;br /&gt;
    currentElement = head    &lt;br /&gt;
    '''while''' true&lt;br /&gt;
      iterator = currentElement.next&lt;br /&gt;
      count = 0&lt;br /&gt;
      '''while''' iterator != currentElement '''and''' count != 2 &lt;br /&gt;
        '''if''' iterator == pointMeeting&lt;br /&gt;
          count++&lt;br /&gt;
        iterator = iterator.next&lt;br /&gt;
      '''if''' count &amp;lt; 2&lt;br /&gt;
        '''break'''&lt;br /&gt;
      currentElement = currentElement.next&lt;br /&gt;
      lengthTail++&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
&lt;br /&gt;
===Реализация за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;===&lt;br /&gt;
Реализацию, приведенную выше можно улучшить. Для этого воспользуемся бинарным поиском. Сначала проверим голову списка, потом сделаем 2 шага вперёд, потом 4, потом 8 и так далее, пока не окажемся на цикле. Теперь у нас есть две позиции {{---}} на левой границе, где мы в хвосте, и на правой {{---}} в цикле. Сделаем бинарный поиск уже по этому отрезку и таким образом найдём цикл за &amp;lt;tex&amp;gt;O(n \log n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Эффективная реализация===&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический (указатель &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка (указатель &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; последнего элемента равен любому другому (не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Достаточно запустить один указатель из &amp;lt;tex&amp;gt;pointMeeting&amp;lt;/tex&amp;gt;, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла. Сложность алгоритма {{---}} &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(Node head, Node pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
====Доказательство корректности алгоритма====&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача про обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
Эта рекурсивная функция принимает указатель на голову списка и предыдущий элемент (при запуске указывать &amp;lt;tex&amp;gt;NULL&amp;lt;/tex&amp;gt;), а возвращает указатель на новую голову списка.&lt;br /&gt;
   &lt;br /&gt;
  Node reverse(Node current, Node prev):&lt;br /&gt;
    '''if''' current == ''NULL''&lt;br /&gt;
      '''return''' prev&lt;br /&gt;
    next = current.next&lt;br /&gt;
    current.next = prev&lt;br /&gt;
    '''return''' reverse(next, current)&lt;br /&gt;
&lt;br /&gt;
Алгоритм корректен, поскольку значения элементов в списке не изменяются, а все указатели &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; изменят свое направление, не нарушив связности самого списка. &lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38806</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=38806"/>
				<updated>2014-06-12T13:32:14Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на поиск цикла в списке */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель (черепаха) переходит к следующему элементу списка, а второй указатель (заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' hasCycle(Node head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический (указатель &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому (не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(Node head, Node pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача про обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      '''return'''&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = current&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38805</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=38805"/>
				<updated>2014-06-12T13:30:57Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на поиск цикла в списке */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель (черепаха) переходит к следующему элементу списка, а второй указатель (заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' hasCycle(head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический (указатель next последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому (не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача про обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      '''return'''&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = current&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38681</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=38681"/>
				<updated>2014-06-11T20:55:50Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на обращение списка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический(указатель next последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача про обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      '''return'''&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = current&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38670</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=38670"/>
				<updated>2014-06-11T19:49:34Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на обращение списка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический(указатель next последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача на обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      '''return'''&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = current&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38669</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=38669"/>
				<updated>2014-06-11T19:48:53Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на обращение списка */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический(указатель next последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача на обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      return&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = current&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38668</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=38668"/>
				<updated>2014-06-11T19:48:18Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead):&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement):&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять {{---}} список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head):&lt;br /&gt;
    tortoise = head&lt;br /&gt;
    hare = head&lt;br /&gt;
    '''repeat'''&lt;br /&gt;
      '''if''' hare == ''NULL'' '''or''' hare.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      tortoise = tortoise.next&lt;br /&gt;
      hare = hair.next.next&lt;br /&gt;
    '''until''' tortoise != hare&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант {{---}} сам список циклический(указатель next последнего элемента равен первому), а второй вариант {{---}} цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting):&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
===Доказательство корректности алгоритма===&lt;br /&gt;
Рассмотрим цикл длиной &amp;lt;tex&amp;gt;N&amp;lt;/tex&amp;gt; с хвостом длины &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt;. Напишем функции для обоих указателей в зависимости от шага &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Очевидно, что встреча не может произойти при &amp;lt;tex&amp;gt;n \leqslant L&amp;lt;/tex&amp;gt;, так как в этом случае &amp;lt;tex&amp;gt;2n&amp;gt;n&amp;lt;/tex&amp;gt; для любого &amp;lt;tex&amp;gt;n&amp;gt;0&amp;lt;/tex&amp;gt;. Тогда положения указателей зададутся следующими функциями (при &amp;lt;tex&amp;gt;n&amp;gt;L&amp;lt;/tex&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_1(n) = L + (n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;f_2(n) = L + (2n-L) \bmod N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приравнивая, получим &amp;lt;tex&amp;gt;n \bmod N = 0&amp;lt;/tex&amp;gt;, или &amp;lt;tex&amp;gt;n = k N, n &amp;gt; L&amp;lt;/tex&amp;gt;.&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; - голова списка, &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; - точка встречи, &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; - первый элемент цикла, &amp;lt;tex&amp;gt;Q&amp;lt;/tex&amp;gt; - расстояние от &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. Тогда в точку &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; можно прийти двумя путями: из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; и из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; через &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; длиной &amp;lt;tex&amp;gt;L + N = X + Q&amp;lt;/tex&amp;gt;, то есть:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + N - X&amp;lt;/tex&amp;gt;, но так как &amp;lt;tex&amp;gt;X = kN&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = L + (1-k) N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть &amp;lt;tex&amp;gt;L = p N + M, 0 &amp;lt;= M &amp;lt; N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Известно, что&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;L &amp;lt; k N \leqslant L + N&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tex&amp;gt;pN + M &amp;lt; kN \leqslant (p+1)N + M&amp;lt;/tex&amp;gt; откуда &amp;lt;tex&amp;gt;k = p + 1&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Подставив полученные значения, получим:&lt;br /&gt;
&amp;lt;tex&amp;gt;Q = pN + M + (1 - p - 1)N = M = L \bmod N&amp;lt;/tex&amp;gt;, откуда следует, что если запустить указатели с одной скоростью из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt;, то они встретятся через &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;. К этому времени вышедший из &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; пройдёт ровно &amp;lt;tex&amp;gt;L&amp;lt;/tex&amp;gt; шагов и остановится в &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, вышедший из &amp;lt;tex&amp;gt;X&amp;lt;/tex&amp;gt; накрутит по циклу &amp;lt;tex&amp;gt;[L/N]&amp;lt;/tex&amp;gt; шагов и пройдёт ещё &amp;lt;tex&amp;gt;Q = L \bmod N&amp;lt;/tex&amp;gt; шагов. Поскольку &amp;lt;tex&amp;gt;L = [L/N] + L \bmod N&amp;lt;/tex&amp;gt;, то они встретятся как раз в точке &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Задача на обращение списка==&lt;br /&gt;
Для того, чтобы обратить список, необходимо пройти по всем элементам этого списка, и все указатели на следующий элемент заменить на предыдущий.&lt;br /&gt;
   &lt;br /&gt;
  '''function''' reverse(head):&lt;br /&gt;
    '''if''' head == ''NULL'' '''or''' head.next == ''NULL''&lt;br /&gt;
      return&lt;br /&gt;
    current = head&lt;br /&gt;
    prev = ''NULL''&lt;br /&gt;
    '''while''' current != ''NULL''&lt;br /&gt;
       next = current.next&lt;br /&gt;
       current.next = prev&lt;br /&gt;
       prev = cur&lt;br /&gt;
       current = next&lt;br /&gt;
    head = prev&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38575</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=38575"/>
				<updated>2014-06-11T15:27:57Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Задача на поиск цикла в списке */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead)&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять - список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head)&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = head.next.next&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      '''if''' secondElement == ''NULL'' '''or''' secondElement.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next.next&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант - сам список циклический(указатель next последнего элемента равен первому), а второй вариант - цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся, будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting)&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38573</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=38573"/>
				<updated>2014-06-11T15:20:54Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
[[Файл: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;
  '''function''' insert(newHead)&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==Задача на поиск цикла в списке==&lt;br /&gt;
Для начала необходимо уметь определять - список циклический или нет. Воспользуемся алгоритмом Флойда &amp;quot;Черепаха и заяц&amp;quot;. Пусть за одну итерацию первый указатель(черепаха) переходит к следующему элементу списка, а второй указатель(заяц) на два элемента вперед. Тогда, если эти два указателя встретятся, то цикл найден, если дошли до конца списка, то цикла нет.&lt;br /&gt;
  '''boolean''' isCycle(head)&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = head.next.next&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      '''if''' secondElement == ''NULL'' '''or''' secondElement.next == ''NULL'' &lt;br /&gt;
        '''return''' ''false''&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next.next&lt;br /&gt;
    '''return''' ''true''&lt;br /&gt;
&lt;br /&gt;
Возможны два варианта цикла в списке. Первый вариант - сам список циклический(указатель next последнего элемента равен первому), а второй вариант - цикл внутри списка(указатель next последнего элемента равен любому другому(не первому). В первом случае найти длину цикла тривиально, во второй случай сводится к первому, если найти указатель на начало цикла. Для того, чтобы его найти, запомним момент, когда в предыдущей функции два указателя оказались равны друг другу. Теперь достаточно запустить один указатель из этого места списка, а другой из головы с одной скоростью. Элемент, где оба указателя встретятся будет началом цикла.&lt;br /&gt;
Ниже приведена функция, которая находит эту точку, а возвращает длину хвоста списка. &lt;br /&gt;
  '''int''' getTail(head, pointMeeting)&lt;br /&gt;
    firstElement = head.next&lt;br /&gt;
    secondElement = pointMeeting.next&lt;br /&gt;
    lengthTail = 1&lt;br /&gt;
    '''while''' firstElement != secondElement&lt;br /&gt;
      firstElement = firstElement.next&lt;br /&gt;
      secondElement = secondElement.next&lt;br /&gt;
      lengthTail = lenghtTail + 1&lt;br /&gt;
    '''return''' lengthTail&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ {{---}} 2-е изд. {{---}} М.: «Вильямс», 2007. {{---}} Глава 11.2. {{---}} ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы {{---}} 2-е изд. {{---}} М.: «Вильямс», 2012. {{---}} Глава 2.2. {{---}} ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38191</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=38191"/>
				<updated>2014-06-09T17:09:32Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Связный список''' (англ. ''List'') {{---}} структура данных, состоящая из элементов, содержащих помимо собственных данных ссылки на следующий и/или предыдущий элемент списка. С помощью списков можно реализовать такие структуры данных как [[стек]] и [[очередь]]. &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;
  '''function''' insert(newHead)&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==См.также==&lt;br /&gt;
* [[Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Linked_list | Wikipedia {{---}} Linked list]]&lt;br /&gt;
* [[wikipedia:ru:Список_(информатика) | Википедия {{---}} Список]]&lt;br /&gt;
* Томас Х. Кормен, Чарльз И. Лейзерсон, Рональд Л. Ривест, Клиффорд Штайн Алгоритмы: построение и анализ — 2-е изд. — М.: «Вильямс», 2007. — Глава 11.2. — ISBN 5-8489-0857-4&lt;br /&gt;
* Дональд Э. Кнут Искусство программирования. Том 1. Основные алгоритмы — 2-е изд. — М.: «Вильямс», 2012. — Глава 2.2. — ISBN 0-201-89685-0&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=38184</id>
		<title>Динамический массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=38184"/>
				<updated>2014-06-09T16:58:16Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Динамический массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к динамическому массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если количество элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; {{---}} константы, зависящие от реализации). Время выполнения операции в худшем случае {{---}} &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex dpi=150&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex dpi=150&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex dpi=150&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex dpi=150&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;2&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;
Динамические массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ динамический массив используется в структуре vector, она описана в STL(&amp;lt;vector&amp;gt;). Стратегия расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит. При инициализации vector по-умолчанию начальный размер равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Java {{---}} ArrayList===&lt;br /&gt;
В Java структура ArrayList основана на динамическом массиве. При превышении максимального на данный момент размера происходит увеличение в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза. Причем начальный размер равен &amp;lt;tex&amp;gt;10&amp;lt;/tex&amp;gt;. Как и в vector, в ArrayList не предусмотрено изменение размера при удалении элементов. Для принудительного изменения размера следует использовать метод trimToSize().&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Dynamic_array | Wikipedia {{---}} Dynamic array]]&lt;br /&gt;
* [[wikipedia:ru:Динамический_массив | Wikipedia {{---}} Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</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=38182</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=38182"/>
				<updated>2014-06-09T16:49:06Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* См.также */&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;
  '''function''' insert(newHead)&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&lt;br /&gt;
==См.также==&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>79.134.198.186</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=38181</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=38181"/>
				<updated>2014-06-09T16:47:29Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Вставка */&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;
  '''function''' insert(newHead)&lt;br /&gt;
    newHead.next = head&lt;br /&gt;
    head = newHead &lt;br /&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;
  '''function''' insertAfter(thisElement, thatElement)&lt;br /&gt;
    thatElement.next = thisElement.next &lt;br /&gt;
    thisElement.next = thatElement&lt;br /&gt;
[[Файл:insertAfter.png|center|490px]]&lt;br /&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&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>79.134.198.186</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=38180</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=38180"/>
				<updated>2014-06-09T16:45:19Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Поиск */&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;
  Node 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;
&lt;br /&gt;
===Удаление===&lt;br /&gt;
Для того, чтобы удалить голову списка, переназначим указатель на голову на второй элемент списка, а голову удалим.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&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>79.134.198.186</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=38179</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=38179"/>
				<updated>2014-06-09T16:40:13Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Удаление */&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;
  '''function''' 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;
[[Файл:removeHead.png|center|430px]]&lt;br /&gt;
Удаление элемента после заданного (&amp;lt;tex&amp;gt;thisElement&amp;lt;/tex&amp;gt;) происходит следующим образом: изменим ссылку на следующий элемент на следующий за удаляемым, затем удалим нужный объект.&lt;br /&gt;
  '''function''' 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;
[[Файл:removeAfter.png|center|550px]]&lt;br /&gt;
&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>79.134.198.186</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=38157</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=38157"/>
				<updated>2014-06-09T14:18:14Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &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>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37311</id>
		<title>Динамический массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37311"/>
				<updated>2014-05-25T19:52:58Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Динамический массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к динамическому массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если количество элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; {{---}} константы, зависящие от реализации). Время выполнения операции в худшем случае {{---}} &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex dpi=150&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex dpi=150&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex dpi=150&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex dpi=150&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;2&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;
Динамические массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ динамический массив используется в структуре vector, она описана в STL(&amp;lt;vector&amp;gt;). Стратегия расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит. При инициализации vector по-умолчанию начальный размер равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Java {{---}} ArrayList===&lt;br /&gt;
В Java структура ArrayList основана на динамическом массиве. При превышении максимального на данный момент размера происходит увеличение в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза. Причем начальный размер равен &amp;lt;tex&amp;gt;10&amp;lt;/tex&amp;gt;. Как и в vector, в ArrayList не предусмотрено изменение размера при удалении элементов. Для принудительного изменения размера следует использовать метод trimToSize().&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Dynamic_array | Wikipedia {{---}} Dynamic array]]&lt;br /&gt;
* [[wikipedia:Динамический_массив | Wikipedia {{---}} Динамический массив]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37303</id>
		<title>Саморасширяющийся массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37303"/>
				<updated>2014-05-25T10:55:44Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Источники информации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Саморасширяющийся массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к саморасширяющемуся массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если кол-во элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; — константы, зависящие от реализации). Время выполнения операции в худшем случае — &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции — &amp;lt;tex&amp;gt;2&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;
Саморасширяющиеся массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ саморасширяющийся массив используется в структуре vector, она описана в STL(&amp;lt;vector&amp;gt;). Стратегия расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит. При инициализации vector по-умолчанию начальный размер равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Java {{---}} ArrayList===&lt;br /&gt;
В Java структура ArrayList основана на саморасширяющемся массиве. При превышении максимального на данный момент размера происходит увеличение в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза. Причем начальный размер равен &amp;lt;tex&amp;gt;10&amp;lt;/tex&amp;gt;. Как и в vector, в ArrayList не предусмотрено изменение размера при удалении элементов. Для принудительного изменения размера следует использовать метод trimToSize().&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Dynamic_array | Wikipedia {{---}} Dynamic_array]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Амортизационный анализ]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37302</id>
		<title>Саморасширяющийся массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37302"/>
				<updated>2014-05-25T10:52:55Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Саморасширяющийся массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к саморасширяющемуся массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если кол-во элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; — константы, зависящие от реализации). Время выполнения операции в худшем случае — &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции — &amp;lt;tex&amp;gt;2&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;
Саморасширяющиеся массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ саморасширяющийся массив используется в структуре vector, она описана в STL(&amp;lt;vector&amp;gt;). Стратегия расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит. При инициализации vector по-умолчанию начальный размер равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Java {{---}} ArrayList===&lt;br /&gt;
В Java структура ArrayList основана на саморасширяющемся массиве. При превышении максимального на данный момент размера происходит увеличение в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза. Причем начальный размер равен &amp;lt;tex&amp;gt;10&amp;lt;/tex&amp;gt;. Как и в vector, в ArrayList не предусмотрено изменение размера при удалении элементов. Для принудительного изменения размера следует использовать метод trimToSize().&lt;br /&gt;
&lt;br /&gt;
==Источники информации==&lt;br /&gt;
* [[wikipedia:Dynamic_array | Wikipedia {{---}} Dynamic_array]]&lt;br /&gt;
&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Саморасширяющийся массив]]&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37301</id>
		<title>Саморасширяющийся массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37301"/>
				<updated>2014-05-25T10:44:19Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* Саморасширяющиеся массивы в современных языках программирования */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Саморасширяющийся массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к саморасширяющемуся массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если кол-во элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; — константы, зависящие от реализации). Время выполнения операции в худшем случае — &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции — &amp;lt;tex&amp;gt;2&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;
Саморасширяющиеся массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ саморасширяющийся массив используется в структуре vector, она описана в STL(&amp;lt;vector&amp;gt;). Стратегия расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит. При инициализации vector по-умолчанию начальный размер равен &amp;lt;tex&amp;gt;0&amp;lt;/tex&amp;gt;.&lt;br /&gt;
===Java {{---}} ArrayList===&lt;br /&gt;
В Java структура ArrayList основана на саморасширяющемся массиве. При превышении максимального на данный момент размера происходит увеличение в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза. Причем начальный размер равен &amp;lt;tex&amp;gt;10&amp;lt;/tex&amp;gt;. Как и в vector, в ArrayList не предусмотрено изменение размера при удалении элементов. Для принудительного изменения размера следует использовать метод trimToSize().&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37143</id>
		<title>Саморасширяющийся массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37143"/>
				<updated>2014-05-20T17:36:33Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: /* С++ {{---}} vector */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Саморасширяющийся массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к саморасширяющемуся массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если кол-во элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; — константы, зависящие от реализации). Время выполнения операции в худшем случае — &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции — &amp;lt;tex&amp;gt;2&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;
Саморасширяющиеся массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ саморасширяющийся массив называется vector, он описан в STL(&amp;lt;vector&amp;gt;). Стратегия его расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшение размера массива никогда не происходит.&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37142</id>
		<title>Саморасширяющийся массив</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%B0%D0%BC%D0%BE%D1%80%D0%B0%D1%81%D1%88%D0%B8%D1%80%D1%8F%D1%8E%D1%89%D0%B8%D0%B9%D1%81%D1%8F_%D0%BC%D0%B0%D1%81%D1%81%D0%B8%D0%B2&amp;diff=37142"/>
				<updated>2014-05-20T17:34:25Z</updated>
		
		<summary type="html">&lt;p&gt;79.134.198.186: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Определение&lt;br /&gt;
| definition =&lt;br /&gt;
'''Массив''' {{---}} набор однотипных переменных, доступ к которым осуществляется по индексу. '''Саморасширяющийся массив''' может изменять свой размер в зависимости от количества элементов в нём.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Операции ==&lt;br /&gt;
Определим операции, которые мы будем применять к саморасширяющемуся массиву:&amp;lt;br&amp;gt;&lt;br /&gt;
=== get(i) ===&lt;br /&gt;
:Возвращает значение &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ой ячейки массива. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== set(i,x) ===&lt;br /&gt;
:В &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ую ячейку массива записывается элемент &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== add(x) ===&lt;br /&gt;
:Добавление в массив элемента &amp;lt;tex&amp;gt;x&amp;lt;/tex&amp;gt;. Время выполнения — &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;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;
=== del() ===&lt;br /&gt;
:Удаляет последний элемент массива. В случае, если кол-во элементов в массиве в &amp;lt;tex&amp;gt;C&amp;lt;/tex&amp;gt; раз меньше его длины, то происходит сжатие в &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; раз. (&amp;lt;tex&amp;gt;C,B&amp;lt;/tex&amp;gt; — константы, зависящие от реализации). Время выполнения операции в худшем случае — &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== size() ===&lt;br /&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;2&amp;lt;/tex&amp;gt; раза, и уменьшается в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза, когда длина массива в &amp;lt;tex&amp;gt;4&amp;lt;/tex&amp;gt; раза больше количества элементов в массиве. В этом случае амортизационная стоимость каждой операции будет &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
=== Метод предоплаты ===&lt;br /&gt;
==== Стоимость операции add(x) ====&lt;br /&gt;
[[Файл:Безымянный1.png|400px|thumb|right|Иллюстрация]]&lt;br /&gt;
Пусть у нас единицей стоимости операции является одна монетка. Тогда при каждой операции '''add(x)''', при которой нам не требуется копирование, мы будем использовать три монетки. Из них одна пойдёт на стоимость самой этой операции, а две будут в резерве (пусть, если мы добавили &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt;-ый элемент, мы будем класть по одной монетке к элементам с номерами &amp;lt;tex&amp;gt;i&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;i-\frac{n}{2}&amp;lt;/tex&amp;gt;). В итоге, к тому моменту, как массив будет заполнен, рядом с каждым элементом будет лежать по одной монетке, которую мы и можем использовать на его копирование в новый массив. Таким образом, амортизационная стоимость каждой операции '''add(x)''' {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, и среднее время её работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
При каждой операции будем использовать три монетки. Одну из них потратим на само удаление элемента, одну монету на элемент, стоящий на позиции &amp;lt;tex&amp;gt;i-\frac{n}{4}&amp;lt;/tex&amp;gt;, и одну монетку на место удаленного элемента. Тогда даже в самом худшем случае (только что расширились, а потом &amp;lt;tex&amp;gt;\frac{n}{4}&amp;lt;/tex&amp;gt; удалили) у нас будет хватать денег на копирование в новый массив.&lt;br /&gt;
=== Метод потенциалов ===&lt;br /&gt;
За потенциал примем число:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;\Phi(c, s) = \begin{cases}&lt;br /&gt;
 2s-c, &amp;amp; \text{if } s\geqslant\frac{1}{2}c \\&lt;br /&gt;
 \frac{1}{2}c-s, &amp;amp; \text{if } s&amp;lt;\frac{1}{2}c&lt;br /&gt;
\end{cases}&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
где &amp;lt;tex&amp;gt;c&amp;lt;/tex&amp;gt; {{---}} размер массива, &amp;lt;tex&amp;gt;s&amp;lt;/tex&amp;gt; {{---}} число элементов массива.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции '''add(x)''' ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c} = 1&amp;lt;/tex&amp;gt;, массив расширяется: &amp;lt;tex dpi=150&amp;gt; a_i = t_i + \Phi(2c, s + 1) - \Phi(c, s) = (s + 1) + (2(s+1)-2c)-(2s-c) = 3 &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;1&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i=t_i+\Phi(c,s+1)-\Phi(c,s)=1+(2(s+1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}\geqslant\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется:&lt;br /&gt;
&amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s+1)-\Phi(c, s)= 1 +(2(s+1)-c)-(\frac{1}{2}c - s)= 3+s-\frac{3}{2}c= 3 + \frac{s}{c}c-\frac{3}{2}c &amp;lt;3+\frac{3}{2}c-\frac{3}{2}c=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;lt;\frac{1}{2}, \frac{s+1}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не расширяется: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s + 1) - \Phi(c, s) = 1 + (\frac{1}{2}c - (s + 1)) - (\frac{1}{2}c - s) = 0&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В итоге, средняя стоимость операции {{---}} &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt;, а среднее время работы {{---}} &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Стоимость операции del() ====&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}=\frac{1}{4}&amp;lt;/tex&amp;gt;, массив сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(\frac{c}{2}, s - 1) - \Phi(c, s) = s + (\frac{1}{2}\cdot\frac{1}{2}c-(s-1)) - (\frac{1}{2}c-s) = 1-\frac{1}{4}c+s=1&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{1}{4}&amp;lt;\frac{s}{c}&amp;lt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (\frac{1}{2}c-(s-1))-(\frac{1}{2}c-s)= 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}\geqslant\frac{1}{2}, \frac{s-1}{c}&amp;lt;\frac{1}{2}\Rightarrow s=\frac{1}{2}c&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) =1 +(\frac{1}{2}c-(s-1))-(2s-c)=2+\frac{3}{2}c-3s = 2&amp;lt;/tex&amp;gt;&lt;br /&gt;
* &amp;lt;tex dpi=150&amp;gt;\frac{s}{c}&amp;gt;\frac{1}{2}&amp;lt;/tex&amp;gt;, массив не сужается: &amp;lt;tex dpi=150&amp;gt;a_i = t_i + \Phi(c, s - 1) - \Phi(c, s) = 1 + (2(s-1)-c)-(2s-c)=3&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Средняя стоимость операции — &amp;lt;tex&amp;gt;2&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;
Саморасширяющиеся массивы широко применяются во многих языках программирования. Рассмотрим, как эта структура данных реализуется в С++ и Java. &lt;br /&gt;
===С++ {{---}} vector===&lt;br /&gt;
В С++ саморасширяющийся массив называется vector, он описан в STL(&amp;lt;vector&amp;gt;). Стратегия его расширения проста: при попытке записи в массив нового элемента в момент полного заполнения памяти происходит увеличение размера в &amp;lt;tex&amp;gt;2&amp;lt;/tex&amp;gt; раза при компиляции GNU C++ и в &amp;lt;tex&amp;gt;1.5&amp;lt;/tex&amp;gt; раза при компиляции Microsoft Visual C++. При удалении элементов уменьшения размера массива никогда не происходит.&lt;/div&gt;</summary>
		<author><name>79.134.198.186</name></author>	</entry>

	</feed>