<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.algo.informatik.tu-darmstadt.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jhohmann</id>
	<title>Algowiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.algo.informatik.tu-darmstadt.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jhohmann"/>
	<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/Special:Contributions/Jhohmann"/>
	<updated>2026-04-22T22:55:36Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.38.4</generator>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1217</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1217"/>
		<updated>2014-10-15T11:33:41Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Further infromation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; contains all nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; further nodes.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt; is the length of a shortes &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path that solely contains nodes not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; (except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; itself, of course). As usual, this means &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; if there is no such path.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &amp;lt;math&amp;gt;\delta(v) \geq \Delta(v)&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
* &amp;lt;math&amp;gt;Q = \empty&amp;lt;/math&amp;gt;, which means that all nodes are reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and have been processed;&lt;br /&gt;
* otherwise, if &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; for the noext node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, which means that &amp;lt;math&amp;gt;\delta(v) = + \infty&amp;lt;/math&amp;gt; for '''every''' node in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; and hence none of the nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# All nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; have to be members of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Root &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; must have correct distance &amp;lt;math&amp;gt;\Delta(s) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The other nodes must meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# &amp;lt;math&amp;gt;\delta(s) := 0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# For all &amp;lt;math&amp;gt;a = (s,v) \in A&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(v) := l(a)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For all &amp;lt;math&amp;gt;v \in V\setminus\{s\}&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;(s,v) \notin A&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;\delta(v) := +\infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Insert all nodes in &amp;lt;math&amp;gt;V\setminus\{s\}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
One node is extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, and the distance values of the endnodes of its outgoing arcs are updated to meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Extract the next node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For each outgoing arc &amp;lt;math&amp;gt;a = (v,w) \in A&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;w \in Q&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(w) := min\{\delta(w), \delta(v) + l(a)\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
The first invariant is trivially maintained. So we will focus on the second and third invariants.&amp;lt;br&amp;gt;&lt;br /&gt;
Consider the moment immediately before the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-iteration. The core of the proof is to show that &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; held at that moment (and hence forever). For a contradiction, suppose there is an &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; whose length is strictly less than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. The third invariant implies that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; has nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; besides &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;. Let &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; denote the first such node on &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Then none of the nodes on the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; belonged to &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; at that moment (except for &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; itself, of course). Due to the [[Paths|prefix property]], this subpath is a shortest &amp;lt;math&amp;gt;(s,u)&amp;lt;/math&amp;gt;-path, so Invariant #3 implies &amp;lt;math&amp;gt;\delta(u) = \Delta(u)&amp;lt;/math&amp;gt;. On the other hand, the specific choice of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; implies &amp;lt;math&amp;gt;\delta(u) \geq \delta(v)&amp;lt;/math&amp;gt;. In summary, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; is not shorter than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. To obtain &amp;lt;math&amp;gt;l(p) &amp;lt; \delta(v)&amp;lt;/math&amp;gt;, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; must have negative total length, which contradicts the prerequisite &amp;lt;math&amp;gt;l \geq 0&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now we know &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; Therefore, &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; fulfills the statement of the second invariant after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. Of course, the second invariant is not violated by any other node either, and is thus maintained.&amp;lt;br&amp;gt;&lt;br /&gt;
For a node &amp;lt;math&amp;gt;w \in V&amp;lt;/math&amp;gt; let &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt; denote the set of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that no node (except for &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; itself) is in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; immediately after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. In particular, the statement of the third invariant means that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the length of a shortest path in &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt;. Tthe induction hypothesis says that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the minimum length of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths in &amp;lt;math&amp;gt;P_{i-1} (w)&amp;lt;/math&amp;gt;. The difference &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; consists of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; is the last arc and all nodes except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; belong to &amp;lt;math&amp;gt;V_{i-1}&amp;lt;/math&amp;gt;. Therefore, the second step of the iteration incorporates &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; in the computation of &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; appropriately to maintain Invaraint #3.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The worst-case complexity is in &amp;lt;math&amp;gt;O(m+T(n)\cdot n)&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;n = |V|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;m = |A|&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;T(n)&amp;lt;/math&amp;gt; is the worst-case compexity for extraction/inserting nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Each node is inserted in and extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; at most once, respectively, which gives &amp;lt;math&amp;gt;O(T(n) \cdot n)&amp;lt;/math&amp;gt; in total. Also, each arc &amp;lt;math&amp;gt;(v,w) \in A&amp;lt;/math&amp;gt; is touched at most once, namely&lt;br /&gt;
* in the initialization if &amp;lt;math&amp;gt;v = s&amp;lt;/math&amp;gt;,&lt;br /&gt;
* when &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;br /&gt;
# We do not need to insert all nodes except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;. In fact, it suffices to initially insert the endnodes of the outgoing arcs of &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and, during an iteration, to insert the nodes of the outgoing arcs of the node that is being extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;. In a sense, the nodes of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; then constitute the &amp;quot;frontierline&amp;quot; of the algorithm. We chose another variant on Dijkstra's algorithm mainly for simplicity of presentation.&lt;br /&gt;
# Clearly, Dijkstra's algorithm also solves the single-source single-target case. In this case, Dijkstra may safely terminate once has been extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;. In fact, the loop invariant implies &amp;lt;math&amp;gt;\delta(t) = \Delta(t)&amp;lt;/math&amp;gt; from then on. This variant on Dijkstra's algorithm is sometimes called the '''early termination variant'''.&lt;br /&gt;
# In a scenario where we perform a large number of searches on the same graph and arc lengths, we do not need to touch the whole graph in each search: &lt;br /&gt;
## We change the algorithm as suggested by the first point: only keep the &amp;quot;frontierline&amp;quot; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
## We also change the algorithm as suggested by the second point: terminate once &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; is processed.&lt;br /&gt;
## To avoid touching all nodes for initializing the &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values, we maintain sort of a '''version counter''', or '''time stamp''', for each node, which holds the ID of the last search that met this node. Whenever a node is met in a search and the node's version counter does not equal the ID of the current search, the distance value of this node is regarded as &amp;lt;math&amp;gt;+ \infty&amp;lt;/math&amp;gt; (no matter what its current value is).&lt;br /&gt;
# The early termination variant may be modified as follows: for and [[Paths|admissible distance function]] &amp;lt;math&amp;gt;h:V \to \R&amp;lt;/math&amp;gt;, replace length &amp;lt;math&amp;gt;l&amp;lt;/math&amp;gt; by &amp;lt;math&amp;gt;l_h&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;l_h(a) := l(a) + h(w) - h(v)&amp;lt;/math&amp;gt; for each &amp;lt;math&amp;gt;a = (v,w) \in A&amp;lt;/math&amp;gt;. This variant is usually called the '''A* algorithm'''. The heristic idea is that we (hopefully) reach &amp;lt;math&amp;gt; t&amp;lt;/math&amp;gt; earlier because the arcs that roughly point towards &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are shortened, and the arcs the roughly point in a direction away from &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; are lengthened.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1216</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1216"/>
		<updated>2014-10-15T11:21:02Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Complexity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; contains all nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; further nodes.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt; is the length of a shortes &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path that solely contains nodes not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; (except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; itself, of course). As usual, this means &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; if there is no such path.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &amp;lt;math&amp;gt;\delta(v) \geq \Delta(v)&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
* &amp;lt;math&amp;gt;Q = \empty&amp;lt;/math&amp;gt;, which means that all nodes are reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and have been processed;&lt;br /&gt;
* otherwise, if &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; for the noext node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, which means that &amp;lt;math&amp;gt;\delta(v) = + \infty&amp;lt;/math&amp;gt; for '''every''' node in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; and hence none of the nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# All nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; have to be members of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Root &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; must have correct distance &amp;lt;math&amp;gt;\Delta(s) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The other nodes must meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# &amp;lt;math&amp;gt;\delta(s) := 0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# For all &amp;lt;math&amp;gt;a = (s,v) \in A&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(v) := l(a)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For all &amp;lt;math&amp;gt;v \in V\setminus\{s\}&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;(s,v) \notin A&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;\delta(v) := +\infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Insert all nodes in &amp;lt;math&amp;gt;V\setminus\{s\}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
One node is extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, and the distance values of the endnodes of its outgoing arcs are updated to meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Extract the next node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For each outgoing arc &amp;lt;math&amp;gt;a = (v,w) \in A&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;w \in Q&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(w) := min\{\delta(w), \delta(v) + l(a)\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
The first invariant is trivially maintained. So we will focus on the second and third invariants.&amp;lt;br&amp;gt;&lt;br /&gt;
Consider the moment immediately before the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-iteration. The core of the proof is to show that &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; held at that moment (and hence forever). For a contradiction, suppose there is an &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; whose length is strictly less than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. The third invariant implies that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; has nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; besides &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;. Let &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; denote the first such node on &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Then none of the nodes on the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; belonged to &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; at that moment (except for &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; itself, of course). Due to the [[Paths|prefix property]], this subpath is a shortest &amp;lt;math&amp;gt;(s,u)&amp;lt;/math&amp;gt;-path, so Invariant #3 implies &amp;lt;math&amp;gt;\delta(u) = \Delta(u)&amp;lt;/math&amp;gt;. On the other hand, the specific choice of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; implies &amp;lt;math&amp;gt;\delta(u) \geq \delta(v)&amp;lt;/math&amp;gt;. In summary, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; is not shorter than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. To obtain &amp;lt;math&amp;gt;l(p) &amp;lt; \delta(v)&amp;lt;/math&amp;gt;, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; must have negative total length, which contradicts the prerequisite &amp;lt;math&amp;gt;l \geq 0&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now we know &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; Therefore, &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; fulfills the statement of the second invariant after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. Of course, the second invariant is not violated by any other node either, and is thus maintained.&amp;lt;br&amp;gt;&lt;br /&gt;
For a node &amp;lt;math&amp;gt;w \in V&amp;lt;/math&amp;gt; let &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt; denote the set of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that no node (except for &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; itself) is in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; immediately after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. In particular, the statement of the third invariant means that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the length of a shortest path in &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt;. Tthe induction hypothesis says that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the minimum length of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths in &amp;lt;math&amp;gt;P_{i-1} (w)&amp;lt;/math&amp;gt;. The difference &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; consists of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; is the last arc and all nodes except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; belong to &amp;lt;math&amp;gt;V_{i-1}&amp;lt;/math&amp;gt;. Therefore, the second step of the iteration incorporates &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; in the computation of &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; appropriately to maintain Invaraint #3.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The worst-case complexity is in &amp;lt;math&amp;gt;O(m+T(n)\cdot n)&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;n = |V|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;m = |A|&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;T(n)&amp;lt;/math&amp;gt; is the worst-case compexity for extraction/inserting nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Each node is inserted in and extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; at most once, respectively, which gives &amp;lt;math&amp;gt;O(T(n) \cdot n)&amp;lt;/math&amp;gt; in total. Also, each arc &amp;lt;math&amp;gt;(v,w) \in A&amp;lt;/math&amp;gt; is touched at most once, namely&lt;br /&gt;
* in the initialization if &amp;lt;math&amp;gt;v = s&amp;lt;/math&amp;gt;,&lt;br /&gt;
* when &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1215</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1215"/>
		<updated>2014-10-15T11:05:51Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; contains all nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; further nodes.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt; is the length of a shortes &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path that solely contains nodes not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; (except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; itself, of course). As usual, this means &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; if there is no such path.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &amp;lt;math&amp;gt;\delta(v) \geq \Delta(v)&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
* &amp;lt;math&amp;gt;Q = \empty&amp;lt;/math&amp;gt;, which means that all nodes are reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and have been processed;&lt;br /&gt;
* otherwise, if &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; for the noext node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, which means that &amp;lt;math&amp;gt;\delta(v) = + \infty&amp;lt;/math&amp;gt; for '''every''' node in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; and hence none of the nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# All nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; have to be members of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Root &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; must have correct distance &amp;lt;math&amp;gt;\Delta(s) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The other nodes must meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# &amp;lt;math&amp;gt;\delta(s) := 0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# For all &amp;lt;math&amp;gt;a = (s,v) \in A&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(v) := l(a)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For all &amp;lt;math&amp;gt;v \in V\setminus\{s\}&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;(s,v) \notin A&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;\delta(v) := +\infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Insert all nodes in &amp;lt;math&amp;gt;V\setminus\{s\}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
One node is extracted from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, and the distance values of the endnodes of its outgoing arcs are updated to meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Extract the next node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For each outgoing arc &amp;lt;math&amp;gt;a = (v,w) \in A&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;w \in Q&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(w) := min\{\delta(w), \delta(v) + l(a)\}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
The first invariant is trivially maintained. So we will focus on the second and third invariants.&amp;lt;br&amp;gt;&lt;br /&gt;
Consider the moment immediately before the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-iteration. The core of the proof is to show that &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; held at that moment (and hence forever). For a contradiction, suppose there is an &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; whose length is strictly less than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. The third invariant implies that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; has nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; besides &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;. Let &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; denote the first such node on &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;. Then none of the nodes on the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; belonged to &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; at that moment (except for &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; itself, of course). Due to the [[Paths|prefix property]], this subpath is a shortest &amp;lt;math&amp;gt;(s,u)&amp;lt;/math&amp;gt;-path, so Invariant #3 implies &amp;lt;math&amp;gt;\delta(u) = \Delta(u)&amp;lt;/math&amp;gt;. On the other hand, the specific choice of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; implies &amp;lt;math&amp;gt;\delta(u) \geq \delta(v)&amp;lt;/math&amp;gt;. In summary, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; is not shorter than &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt;. To obtain &amp;lt;math&amp;gt;l(p) &amp;lt; \delta(v)&amp;lt;/math&amp;gt;, the subpath of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; from &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; must have negative total length, which contradicts the prerequisite &amp;lt;math&amp;gt;l \geq 0&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Now we know &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; Therefore, &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; fulfills the statement of the second invariant after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. Of course, the second invariant is not violated by any other node either, and is thus maintained.&amp;lt;br&amp;gt;&lt;br /&gt;
For a node &amp;lt;math&amp;gt;w \in V&amp;lt;/math&amp;gt; let &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt; denote the set of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that no node (except for &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; itself) is in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; immediately after the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration. In particular, the statement of the third invariant means that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the length of a shortest path in &amp;lt;math&amp;gt;P_i (w)&amp;lt;/math&amp;gt;. Tthe induction hypothesis says that &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; is the minimum length of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths in &amp;lt;math&amp;gt;P_{i-1} (w)&amp;lt;/math&amp;gt;. The difference &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; consists of all &amp;lt;math&amp;gt;(s,w)&amp;lt;/math&amp;gt;-paths such that &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; is the last arc and all nodes except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; belong to &amp;lt;math&amp;gt;V_{i-1}&amp;lt;/math&amp;gt;. Therefore, the second step of the iteration incorporates &amp;lt;math&amp;gt;P_i (w) \setminus P_{i-1} (w)&amp;lt;/math&amp;gt; in the computation of &amp;lt;math&amp;gt;\delta(w)&amp;lt;/math&amp;gt; appropriately to maintain Invaraint #3.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1214</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1214"/>
		<updated>2014-10-15T10:40:41Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction basis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; contains all nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; further nodes.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt; is the length of a shortes &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path that solely contains nodes not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; (except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; itself, of course). As usual, this means &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; if there is no such path.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &amp;lt;math&amp;gt;\delta(v) \geq \Delta(v)&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
* &amp;lt;math&amp;gt;Q = \empty&amp;lt;/math&amp;gt;, which means that all nodes are reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and have been processed;&lt;br /&gt;
* otherwise, if &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; for the noext node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, which means that &amp;lt;math&amp;gt;\delta(v) = + \infty&amp;lt;/math&amp;gt; for '''every''' node in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; and hence none of the nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# All nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; have to be members of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Root &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; must have correct distance &amp;lt;math&amp;gt;\Delta(s) = 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The other nodes must meet Invariant #3.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# &amp;lt;math&amp;gt;\delta(s) := 0&amp;lt;/math&amp;gt;;&lt;br /&gt;
# For all &amp;lt;math&amp;gt;a = (s,v) \in A&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;\delta(v) := l(a)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For all &amp;lt;math&amp;gt;v \in V\setminus\{s\}&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;(s,v) \notin A&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;\delta(v) := +\infty&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Insert all nodes in &amp;lt;math&amp;gt;V\setminus\{s\}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1213</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1213"/>
		<updated>2014-10-15T10:31:00Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Abstract view */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; contains all nodes of &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; except for &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; further nodes.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For the nodes &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\delta(v)&amp;lt;/math&amp;gt; is the length of a shortes &amp;lt;math&amp;gt;(s,v)&amp;lt;/math&amp;gt;-path that solely contains nodes not in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; (except for &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; itself, of course). As usual, this means &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; if there is no such path.&lt;br /&gt;
&lt;br /&gt;
In particular, it is &amp;lt;math&amp;gt;\delta(v) \geq \Delta(v)&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
* &amp;lt;math&amp;gt;Q = \empty&amp;lt;/math&amp;gt;, which means that all nodes are reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; and have been processed;&lt;br /&gt;
* otherwise, if &amp;lt;math&amp;gt;\delta(v) = +\infty&amp;lt;/math&amp;gt; for the noext node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;, which means that &amp;lt;math&amp;gt;\delta(v) = + \infty&amp;lt;/math&amp;gt; for '''every''' node in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; and hence none of the nodes in &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is reachable from &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1212</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1212"/>
		<updated>2014-10-15T10:14:22Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further infromation ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1205</id>
		<title>Dijkstra</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Dijkstra&amp;diff=1205"/>
		<updated>2014-10-13T19:16:27Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Graph Algorithms]]&lt;br /&gt;
[[Category:All Pairs Shortest Paths]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Dijkstra&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/dijkstra-2310 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Dijstra's algorithm''' is a graph algortihm solving the single-source shortest-paths problem.&lt;br /&gt;
&lt;br /&gt;
== Requirements == &lt;br /&gt;
&lt;br /&gt;
* directed Graph &amp;lt;math&amp;gt;G=(V,E)&amp;lt;/math&amp;gt;&lt;br /&gt;
* weight function &amp;lt;math&amp;gt;w\colon E\to\mathbb R&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;\forall(u,v)\in E\colon w(u,v)\geq 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* source &amp;lt;math&amp;gt;s\in V&amp;lt;/math&amp;gt;&lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; &lt;br /&gt;
* Datastruct &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Single source shortest paths]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisities:''' For all &amp;lt;math&amp;gt;\alpha \in A&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;l(a) \geq 0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Type of algortihm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
# A temporary '''distance value''' &amp;lt;math&amp;gt;\delta(v) \in \R&amp;lt;/math&amp;gt; for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;. At termination, it is &amp;lt;math&amp;gt;\delta(v) = \Delta(v)&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A [[bounded priority queue]] &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; of size &amp;lt;math&amp;gt;|V|-1&amp;lt;/math&amp;gt;, which contains nodes from &amp;lt;math&amp;gt;V&amp;lt;/math&amp;gt; and takes their &amp;lt;math&amp;gt;\delta&amp;lt;/math&amp;gt;-values as keys. The node with minimal key is returned.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====DIJKSTRA(''G,w,s'')====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 DIJKSTRA(''G,w,s'')&lt;br /&gt;
 1 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 2      ''S'' = &amp;amp;empty;&lt;br /&gt;
 3      ''Q'' = ''G.V''&lt;br /&gt;
 4      '''while''' ''Q'' &amp;amp;ne; &amp;amp;empty;&lt;br /&gt;
 5            ''u'' = EXTRACT-MIN(''Q'')&lt;br /&gt;
 6            ''S'' = ''S'' &amp;amp;cup; {''u''} &lt;br /&gt;
 7            '''for''' each vertex ''v'' &amp;amp;isin; G.''Adj''[''u'']&lt;br /&gt;
 8                 RELAX(''u,v,w'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====RELAX(''u,v,w'')====&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 RELAX(''u,v,w'')&lt;br /&gt;
 1 '''if''' ''v.d'' &amp;gt; ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 2       ''v.d'' = ''u.d'' + ''w''(''u,v'')&lt;br /&gt;
 3       ''v.&amp;amp;pi;'' = ''u''&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
====INITIALIZE-SINGLE-SOURCE(''G,s'')====&lt;br /&gt;
 INITIALIZE-SINGLE-SOURCE(''G,s'') &lt;br /&gt;
 1 '''for''' each vertex ''v'' &amp;amp;isin; ''G.V''&lt;br /&gt;
 2         ''v.d'' = &amp;amp;infin;&lt;br /&gt;
 3         ''v.&amp;amp;pi;'' = NIL&lt;br /&gt;
 4 ''s.d'' = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubblesort&amp;diff=694</id>
		<title>Bubblesort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubblesort&amp;diff=694"/>
		<updated>2014-10-06T15:12:34Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bubble Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bubble-sort-1940 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gerneral information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations, the elements of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; at the positions &amp;lt;math&amp;gt;|S| - i + 1,\dots,|S|&amp;lt;/math&amp;gt; are placed at their correct positions in sorting order.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i = |S| - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Step-by-step, move the maximum element seen so far to the position &amp;lt;math&amp;gt;|S| - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' For &amp;lt;math&amp;gt;j := 2,\dots,|S|-i+1&amp;lt;/math&amp;gt; (in this order): If &amp;lt;math&amp;gt;S[j-1] &amp;gt; S[j]&amp;lt;/math&amp;gt;, swap &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' The loop invariant of the inner loop is this: after &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; iterations of the inner loop, &amp;lt;math&amp;gt;S[m+1]&amp;lt;/math&amp;gt; is the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[m+1]&amp;lt;/math&amp;gt; To see that invariant, note that the induction hypothesis implies for an iteration on index &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; that &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; is the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[j-1]&amp;lt;/math&amp;gt;. So, if &amp;lt;math&amp;gt;S[j-1] &amp;gt; S[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; is also the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[j]&amp;lt;/math&amp;gt;. Therefore, swapping &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt; maintains the invariant. On the other hand, if &amp;lt;math&amp;gt;S[j-1] \leq S[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt; is already the maximum, so doing nothing maintains the invariant in this case.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(^2)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' The asymptotic complexity of the inner loop in the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration of the outer loop is in &amp;lt;math&amp;gt;\Theta(n-i)&amp;lt;/math&amp;gt;. Therefore, the total complexity is in &amp;lt;math&amp;gt;\Theta\left(\sum_{i=1}^{n-1} (n-i)\right) = \Theta\left(\sum_{i=1}^{n-1}i\right) = \Theta\left(\frac{n(n-1)}{2}\right) = \Theta(n^2)&amp;lt;/math&amp;gt;.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bounded_priority_queue&amp;diff=603</id>
		<title>Bounded priority queue</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bounded_priority_queue&amp;diff=603"/>
		<updated>2014-10-02T22:11:22Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* General information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
[[Category:Checkup]]&lt;br /&gt;
[[Category:Abstract Data Structure]]&lt;br /&gt;
[[Category:Sequence]]&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Representation invariant:'''&lt;br /&gt;
# This abstract data structure is [[Genericity|generic]] and parameterized by a fixed '''key type''' &amp;lt;math&amp;gt;\mathcal{K}&amp;lt;/math&amp;gt; and a fixed [[comparison]] &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; defined on &amp;lt;math&amp;gt;\mathcal{K}&amp;lt;/math&amp;gt;.&lt;br /&gt;
# An object with key type &amp;lt;math&amp;gt;\mathcal{K}&amp;lt;/math&amp;gt; represents a finite, dynamically changing [[multiset]], of elements of type &amp;lt;math&amp;gt;\mathcal{K}&amp;lt;/math&amp;gt; (the multiset may be empty).&lt;br /&gt;
# An object has two additional attributes, which are natural numbers:&lt;br /&gt;
## Attribute &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; stores the current number of elements (in particular, &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; is dynamically changing).&lt;br /&gt;
## Attribute &amp;lt;math&amp;gt;N_\text{max}\in\mathrm{N}&amp;lt;/math&amp;gt; is the maximum number of elements that can be stored in the queue (&amp;lt;math&amp;gt;N_\text{max}&amp;lt;/math&amp;gt; is constant throughout the object's life time).&lt;br /&gt;
# Therefore, at any moment, it is &amp;lt;math&amp;gt;n\le N_\text{max}&amp;lt;/math&amp;gt;.&lt;br /&gt;
'''Constructor:''' Gets a [[comparison]] &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; and a natural number &amp;lt;math&amp;gt;N_\text{max}&amp;lt;/math&amp;gt;, and initializes the queue so as to be empty with a maximum capacity of &amp;lt;math&amp;gt;N_\text{max}&amp;lt;/math&amp;gt; items.&lt;br /&gt;
&lt;br /&gt;
== Method ==&lt;br /&gt;
'''Name:''' insert&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A key &amp;lt;math&amp;gt;K\in N_\text{max}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Output:''' A unique ID (natural number), which is permanently associated with the inserted key, until the key is extracted from the queue.&lt;br /&gt;
&lt;br /&gt;
'''Precondition:''' It is &amp;lt;math&amp;gt;n&amp;lt;N_\text{max}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Postcondition:''' The input key &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is inserted into the queue (a.k.a. ''enqueued'').&lt;br /&gt;
&lt;br /&gt;
== Method ==&lt;br /&gt;
'''Name:''' extract minimum&lt;br /&gt;
&lt;br /&gt;
'''Input:''' -&lt;br /&gt;
&lt;br /&gt;
'''Output:''' Returns the minimum key &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; that is currently stored in the queue.&lt;br /&gt;
&lt;br /&gt;
'''Precondition:''' It is &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Postcondition:''' For the minimum key currently stored in the queue, one occurrence is removed (a.k.a. ''dequeued'').&lt;br /&gt;
&lt;br /&gt;
== Method ==&lt;br /&gt;
'''Name:''' find minimum&lt;br /&gt;
&lt;br /&gt;
'''Input:''' -&lt;br /&gt;
&lt;br /&gt;
'''Output:''' Returns the minimum key &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; currently stored in the queue.&lt;br /&gt;
&lt;br /&gt;
'''Precondition:''' It is &amp;lt;math&amp;gt;n&amp;gt;0&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Postcondition:''' -&lt;br /&gt;
&lt;br /&gt;
== Method ==&lt;br /&gt;
'''Name:''' decrease key&lt;br /&gt;
&lt;br /&gt;
'''Input:''' A natural number &amp;lt;math&amp;gt;ID&amp;lt;/math&amp;gt; and a real number &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Output:''' -&lt;br /&gt;
&lt;br /&gt;
'''Precondition:'''&lt;br /&gt;
# The input is the ID of some queue element (returned on insertion).&lt;br /&gt;
# The value of &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; is not larger than the current value of the key to which ID refers.&lt;br /&gt;
&lt;br /&gt;
'''Postcondition:''' The key to which ID refers is now &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; (the old value of that key is lost).&lt;br /&gt;
&lt;br /&gt;
== Method ==&lt;br /&gt;
'''Name:''' number&lt;br /&gt;
&lt;br /&gt;
'''Input:''' -&lt;br /&gt;
&lt;br /&gt;
'''Output:''' The value of attribute &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;, that is, the number of keys currently stored in the queue.&lt;br /&gt;
&lt;br /&gt;
'''Precondition:''' -&lt;br /&gt;
&lt;br /&gt;
'''Postcondition:''' -&lt;br /&gt;
&lt;br /&gt;
== Known implementations ==&lt;br /&gt;
[[Heap as array]]&lt;br /&gt;
&lt;br /&gt;
== Remark ==&lt;br /&gt;
&lt;br /&gt;
== Reference ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree:_find&amp;diff=602</id>
		<title>Binary search tree: find</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree:_find&amp;diff=602"/>
		<updated>2014-10-02T22:07:26Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* General Information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Binary_Search_Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Binary Search Tree&amp;lt;br&amp;gt;Find&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;[[Sorted sequence]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/binary-search-tree-1938 Openlearnware]&amp;lt;br&amp;gt;See Chapter 2,3&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic Problem:''' [[Sorted sequence#Find|Sorted Sequence:find]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''  A pointer '''''p''''' of type &amp;quot;pointer to binary search tree node of type &amp;lt;math&amp;gt;\kappa&amp;lt;/math&amp;gt;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i\geq 0&amp;lt;/math&amp;gt; Iterations.&lt;br /&gt;
# The pointer '''''p''''' points to a tree node '''''v''''' on height level '''''i''''' (or is void). &lt;br /&gt;
# The key '''''K''''' is in the range of '''''v'''''.&lt;br /&gt;
'''Variant:''' '''''i''''' is increased by 1.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' Either it is &amp;lt;math&amp;gt;p = void&amp;lt;/math&amp;gt; or, otherwise, &amp;lt;math&amp;gt;p.key = K&amp;lt;/math&amp;gt;.&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
'''Abstract view:''' Set '''''p''''':= '''''root'''''.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
'''Abstract view:''' If '''''p''''' points to a node but not with key '''''K''''', '''''p''''' descends in the appropriate direction, left or right.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# If &amp;lt;math&amp;gt;p = void&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# Otherwise, if &amp;lt;math&amp;gt;p.key = K&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''true'''''.&lt;br /&gt;
# Otherwise:&lt;br /&gt;
## If &amp;lt;math&amp;gt;K &amp;lt; p.key&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p := left&amp;lt;/math&amp;gt;.&lt;br /&gt;
## If &amp;lt;math&amp;gt;K &amp;gt; p.key&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p := right&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctnes:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' Linear in the length of the sequence in the worst case (more precisely, linear in the height of the tree).&lt;br /&gt;
[[File:wcbst.png|300px|thumb|right|Worst case binary search tree]]&lt;br /&gt;
'''Proof:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
TREE-SEARCH (x, k)&lt;br /&gt;
:if x= NIL or k = key[x]&lt;br /&gt;
::then return x&lt;br /&gt;
:if k &amp;lt; key[x]&lt;br /&gt;
::then return TREE-SEARCH(left[x], k)&lt;br /&gt;
:else return TREE-SEARCH(right[x], k)&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=601</id>
		<title>Bucketsort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=601"/>
		<updated>2014-10-02T22:04:39Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bucket Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bucket-sort-1941 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting sequences of strings]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Axiliary data:'''&lt;br /&gt;
# An ordered sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; of strings, which will eventually hold the overall result of the algorithm.&lt;br /&gt;
# The '''buckets''', that is, an array &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; whose index range contains the ID range of &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; (e.g. 26 for the alphabet) and whose components are [[Sets and sequences|ordered sequences]] of strings.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; denote the maximum length of an input string.&lt;br /&gt;
# An array &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; with index range &amp;lt;math&amp;gt;[1,\dots,N]&amp;lt;/math&amp;gt; and [[Sets and sequences|multisets]] of strings as components.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# For &amp;lt;math&amp;gt;j \in \{1,\dots,N-i\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;A[j]&amp;lt;/math&amp;gt; contains all input strings of length &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; contains all other input strings, that is, the ones with length at least &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;. The sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; is sorted according to the following definition of comparison: &amp;lt;math&amp;gt;str1 &amp;lt; str2&amp;lt;/math&amp;gt; (resp. &amp;lt;math&amp;gt;str1 \leq str2&amp;lt;/math&amp;gt;) means that the substring of &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt; is lexicographically smaller (resp., smaller or equal) than the substring of &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# All buckets are empty.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Break condition: &amp;lt;math&amp;gt;i = N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' The auxiliary data must be initialized.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# &amp;lt;math&amp;gt;S' := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# For each &amp;lt;math&amp;gt;c \in \Sigma&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;B[c] := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# For each &amp;lt;math&amp;gt;i \in \{1,\dots,N\}, set &amp;lt;math&amp;gt;A[i] := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# Move each string &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;A[l(str)]&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;l(str)&amp;lt;/math&amp;gt; denotes the length of &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
'''Abstract view:'''&lt;br /&gt;
# Move each string &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;A[N-i+1]&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;B[str[N-i+1]]&amp;lt;/math&amp;gt;&lt;br /&gt;
# Afterwards: Append each string &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; at the tail of &amp;lt;math&amp;gt;B[str[N - i + 1]]&amp;lt;/math&amp;gt;. It is essential that the strings are considered in the order in which they are stored in &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt;. (Now &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; is empty.)&lt;br /&gt;
# Fore each &amp;lt;math&amp;gt;c \in \Sigma&amp;lt;/math&amp;gt; in ascending order: append &amp;lt;math&amp;gt;B[c]&amp;lt;/math&amp;gt; at the tail of &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; and make &amp;lt;math&amp;gt;B[c]&amp;lt;/math&amp;gt; empty.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' We have to show that the relative order of each pair of strings, &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt;, in the new sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; are correct. For that, we distinguish between four cases:&lt;br /&gt;
# If &amp;lt;math&amp;gt;str1[N-i+1] \neq str2[N-i+1]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt; are placed in different buckets in Step 3 of the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration, so they are correctly ordered according to the character at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;str1[N-i+1] = str2[N-i+1]&amp;lt;/math&amp;gt; and both strings have length &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;, their relative order is irrelevant, so nothing is to show.&lt;br /&gt;
# Next, consider the case that &amp;lt;math&amp;gt;str1[N-i+1] = str2[N-i+1]&amp;lt;/math&amp;gt;, one string (say, &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt;) has length &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt; and the other one (&amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt;) has a length strictly greater than &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;. Since the strings of length &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt; are placed in their buckets prior to the longer strings (cf. Steps 1 and 2), &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt; appears after &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt;, which is correct.&lt;br /&gt;
# Finally, consider the case that &amp;lt;math&amp;gt;str1[N-i+1] = str2[N-i+1]&amp;lt;/math&amp;gt;, and the lengths of both strings are larger than &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;. Then the induction hypothesis guarantees the correct relative order due to the specific order in which the strings are considered in Step 2&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' Let &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; denote the total sum of all input string lengths. Then the asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(M)&amp;lt;/math&amp;gt; in the best and the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obviously, the preprocessing takes &amp;lt;mathO(M)&amp;lt;/math&amp;gt; time.&lt;br /&gt;
In the main loop, each character of each string is read exactly once. Obviously, no operation is applied more often than the reading of single characters.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=600</id>
		<title>Bucketsort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=600"/>
		<updated>2014-10-02T21:49:38Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction basis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bucket Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bucket-sort-1941 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting sequences of strings]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Axiliary data:'''&lt;br /&gt;
# An ordered sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; of strings, which will eventually hold the overall result of the algorithm.&lt;br /&gt;
# The '''buckets''', that is, an array &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; whose index range contains the ID range of &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; (e.g. 26 for the alphabet) and whose components are [[Sets and sequences|ordered sequences]] of strings.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; denote the maximum length of an input string.&lt;br /&gt;
# An array &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; with index range &amp;lt;math&amp;gt;[1,\dots,N]&amp;lt;/math&amp;gt; and [[Sets and sequences|multisets]] of strings as components.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# For &amp;lt;math&amp;gt;j \in \{1,\dots,N-i\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;A[j]&amp;lt;/math&amp;gt; contains all input strings of length &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; contains all other input strings, that is, the ones with length at least &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;. The sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; is sorted according to the following definition of comparison: &amp;lt;math&amp;gt;str1 &amp;lt; str2&amp;lt;/math&amp;gt; (resp. &amp;lt;math&amp;gt;str1 \leq str2&amp;lt;/math&amp;gt;) means that the substring of &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt; is lexicographically smaller (resp., smaller or equal) than the substring of &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# All buckets are empty.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Break condition: &amp;lt;math&amp;gt;i = N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' The auxiliary data must be initialized.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# &amp;lt;math&amp;gt;S' := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# For each &amp;lt;math&amp;gt;c \in \Sigma&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;B[c] := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# For each &amp;lt;math&amp;gt;i \in \{1,\dots,N\}, set &amp;lt;math&amp;gt;A[i] := \emptyset&amp;lt;/math&amp;gt;&lt;br /&gt;
# Move each string &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;A[l(str)]&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;l(str)&amp;lt;/math&amp;gt; denotes the length of &amp;lt;math&amp;gt;str&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' Let &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; denote the total sum of all input string lengths. Then the asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(M)&amp;lt;/math&amp;gt; in the best and the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obviously, the preprocessing takes &amp;lt;mathO(M)&amp;lt;/math&amp;gt; time.&lt;br /&gt;
In the main loop, each character of each string is read exactly once. Obviously, no operation is applied more often than the reading of single characters.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=599</id>
		<title>Bucketsort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=599"/>
		<updated>2014-10-02T21:44:42Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Abstract view */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bucket Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bucket-sort-1941 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting sequences of strings]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Axiliary data:'''&lt;br /&gt;
# An ordered sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; of strings, which will eventually hold the overall result of the algorithm.&lt;br /&gt;
# The '''buckets''', that is, an array &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; whose index range contains the ID range of &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; (e.g. 26 for the alphabet) and whose components are [[Sets and sequences|ordered sequences]] of strings.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; denote the maximum length of an input string.&lt;br /&gt;
# An array &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; with index range &amp;lt;math&amp;gt;[1,\dots,N]&amp;lt;/math&amp;gt; and [[Sets and sequences|multisets]] of strings as components.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# For &amp;lt;math&amp;gt;j \in \{1,\dots,N-i\}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;A[j]&amp;lt;/math&amp;gt; contains all input strings of length &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; contains all other input strings, that is, the ones with length at least &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;. The sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; is sorted according to the following definition of comparison: &amp;lt;math&amp;gt;str1 &amp;lt; str2&amp;lt;/math&amp;gt; (resp. &amp;lt;math&amp;gt;str1 \leq str2&amp;lt;/math&amp;gt;) means that the substring of &amp;lt;math&amp;gt;str1&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt; is lexicographically smaller (resp., smaller or equal) than the substring of &amp;lt;math&amp;gt;str2&amp;lt;/math&amp;gt; starting at position &amp;lt;math&amp;gt;N - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# All buckets are empty.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Break condition: &amp;lt;math&amp;gt;i = N&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' Let &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; denote the total sum of all input string lengths. Then the asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(M)&amp;lt;/math&amp;gt; in the best and the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obviously, the preprocessing takes &amp;lt;mathO(M)&amp;lt;/math&amp;gt; time.&lt;br /&gt;
In the main loop, each character of each string is read exactly once. Obviously, no operation is applied more often than the reading of single characters.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=598</id>
		<title>Bucketsort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=598"/>
		<updated>2014-10-02T21:36:32Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Complexity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bucket Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bucket-sort-1941 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting sequences of strings]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Axiliary data:'''&lt;br /&gt;
# An ordered sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; of strings, which will eventually hold the overall result of the algorithm.&lt;br /&gt;
# The '''buckets''', that is, an array &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; whose index range contains the ID range of &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; (e.g. 26 for the alphabet) and whose components are [[Sets and sequences|ordered sequences]] of strings.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; denote the maximum length of an input string.&lt;br /&gt;
# An array &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; with index range &amp;lt;math&amp;gt;[1,\dots,N]&amp;lt;/math&amp;gt; and [[Sets and sequences|multisets]] of strings as components.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' Let &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; denote the total sum of all input string lengths. Then the asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(M)&amp;lt;/math&amp;gt; in the best and the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obviously, the preprocessing takes &amp;lt;mathO(M)&amp;lt;/math&amp;gt; time.&lt;br /&gt;
In the main loop, each character of each string is read exactly once. Obviously, no operation is applied more often than the reading of single characters.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=597</id>
		<title>Bucketsort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bucketsort&amp;diff=597"/>
		<updated>2014-10-02T21:35:15Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Bucket Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/bucket-sort-1941 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting sequences of strings]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Axiliary data:'''&lt;br /&gt;
# An ordered sequence &amp;lt;math&amp;gt;S'&amp;lt;/math&amp;gt; of strings, which will eventually hold the overall result of the algorithm.&lt;br /&gt;
# The '''buckets''', that is, an array &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; whose index range contains the ID range of &amp;lt;math&amp;gt;\Sigma&amp;lt;/math&amp;gt; (e.g. 26 for the alphabet) and whose components are [[Sets and sequences|ordered sequences]] of strings.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; denote the maximum length of an input string.&lt;br /&gt;
# An array &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; with index range &amp;lt;math&amp;gt;[1,\dots,N]&amp;lt;/math&amp;gt; and [[Sets and sequences|multisets]] of strings as components.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Selection_sort&amp;diff=596</id>
		<title>Selection sort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Selection_sort&amp;diff=596"/>
		<updated>2014-10-02T21:21:22Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Selection Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/selection-sort-1948 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt;iterations: The elements at positions &amp;lt;math&amp;gt;|S|-i+1,\dots,|S|&amp;lt;/math&amp;gt; are correctly placed in sorting order.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i = |S| - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Identify the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[|S|-i+1]&amp;lt;/math&amp;gt; and then move it, by a swap, to position |S|-i+1.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# Set &amp;lt;math&amp;gt;m := 1&amp;lt;/math&amp;gt;&lt;br /&gt;
# For all &amp;lt;math&amp;gt;j=2,\dots,|S|-i+1&amp;lt;/math&amp;gt;: If &amp;lt;math&amp;gt;S[j] &amp;gt; S[m]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;m := j&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Swap &amp;lt;math&amp;gt;S[m]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[|S|-i+1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' Follows immediately from the invariant of the inner loop: &amp;lt;math&amp;gt;S[m]&amp;lt;/math&amp;gt; is the maximum element out of &amp;lt;math&amp;gt;S[1],\dots,S[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement: The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' The asymptotic complexity of the inner loop in the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration of the outer loop is in &amp;lt;math&amp;gt;\Theta(n - i)&amp;lt;/math&amp;gt;. Therefore, the total complexity is in &amp;lt;math&amp;gt;\Theta\left(\sum_{i=1}^{n-1} (n-i) \right) = \Theta\left(\sum_{i=1}^{n-1} i \right) = \Theta\left(\frac{n(n-1)}{2} \right) = \Theta\left(n^2\right)&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=595</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=595"/>
		<updated>2014-10-02T17:02:06Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Proof: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;, and for &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(i,j)&amp;lt;/math&amp;gt; denote the probability that the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and the &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-th elemet of the eventual, sorted sequence are compared throughtout the algorithm. Using this notation, we may rewrite the above summation as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y) = \sum_{i=1}^{n-1} \sum_{j = i+1}^{n} Pr(i,j)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;i &amp;lt; j&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt; S_{ij}&amp;lt;/math&amp;gt; denote the subsequence of the eventual, sorted sequence that starts with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; and ends with &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. The elements &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; are compared if, and only if, &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; is the very first element of &amp;lt;math&amp;gt;S_{ij}&amp;lt;/math&amp;gt; to be chosen as a pivot. The probability of this event is &amp;lt;math&amp;gt;\frac{2}{|S_{ij}|} = \frac{2}{j - i + 1}&amp;lt;/math&amp;gt;, so we obtain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;k := j-i&amp;lt;/math&amp;gt;, this gives&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1} = \sum_{i=1}^{n-1} \sum_{k=1}^{n} \frac{2}{k+1} \leq 2(n - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k=1}^n \frac{1}{k+1} \leq 2(n-1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k+1}^n \frac{1}{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The [http://en.wikipedia.org/wiki/Harmonic_series_(mathematics)#Rate_of_divergence asymptotic behavior] of the [http://en.wikipedia.org/wiki/Harmonic_series_(mathematics) harmonic series] is &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt;, so the last expression is &amp;lt;math&amp;gt;\Theta(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; is an array, &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; cannot be decomposed into subsequences. We would liko to avoid the need for additional arrays and copy operations. Instead, the array should be sorted in-place, that is, by swap operations on pairs of elements. The auxiliary procedure, [[Pivot partitioning by scanning]], is designed exactly for that: it permutes the array such that each of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; is a subarray. Then each recursive call of Quicksort operates on a subarray of the input array, which is specified by two index pointers.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=594</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=594"/>
		<updated>2014-10-02T17:00:31Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Further information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;, and for &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(i,j)&amp;lt;/math&amp;gt; denote the probability that the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and the &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-th elemet of the eventual, sorted sequence are compared throughtout the algorithm. Using this notation, we may rewrite the above summation as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y) = \sum_{i=1}^{n-1} \sum_{j = i+1}^{n} Pr(i,j)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;i &amp;lt; j&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt; S_{ij}&amp;lt;/math&amp;gt; denote the subsequence of the eventual, sorted sequence that starts with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; and ends with &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. The elements &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; are compared if, and only if, &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; is the very first element of &amp;lt;math&amp;gt;S_{ij}&amp;lt;/math&amp;gt; to be chosen as a pivot. The probability of this event is &amp;lt;math&amp;gt;\frac{2}{|S_{ij}|} = \frac{2}{j - i + 1}&amp;lt;/math&amp;gt;, so we obtain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;k := j-i&amp;lt;/math&amp;gt;, this gives&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1} = \sum_{i=1}^{n-1} \sum_{k=1}^{n} \frac{2}{k+1} \leq 2(n - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k=1}^n \frac{1}{k+1} \leq 2(n-1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k+1}^n \frac{1}{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The asymptotic behavior of the harmonic series is &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt;, so the last expression is &amp;lt;math&amp;gt;\Theta(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; is an array, &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; cannot be decomposed into subsequences. We would liko to avoid the need for additional arrays and copy operations. Instead, the array should be sorted in-place, that is, by swap operations on pairs of elements. The auxiliary procedure, [[Pivot partitioning by scanning]], is designed exactly for that: it permutes the array such that each of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; is a subarray. Then each recursive call of Quicksort operates on a subarray of the input array, which is specified by two index pointers.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=593</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=593"/>
		<updated>2014-10-02T16:59:17Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Further information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;, and for &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(i,j)&amp;lt;/math&amp;gt; denote the probability that the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and the &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-th elemet of the eventual, sorted sequence are compared throughtout the algorithm. Using this notation, we may rewrite the above summation as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y) = \sum_{i=1}^{n-1} \sum_{j = i+1}^{n} Pr(i,j)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;i &amp;lt; j&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt; S_{ij}&amp;lt;/math&amp;gt; denote the subsequence of the eventual, sorted sequence that starts with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; and ends with &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. The elements &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; are compared if, and only if, &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; is the very first element of &amp;lt;math&amp;gt;S_{ij}&amp;lt;/math&amp;gt; to be chosen as a pivot. The probability of this event is &amp;lt;math&amp;gt;\frac{2}{|S_{ij}|} = \frac{2}{j - i + 1}&amp;lt;/math&amp;gt;, so we obtain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;k := j-i&amp;lt;/math&amp;gt;, this gives&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1} = \sum_{i=1}^{n-1} \sum_{k=1}^{n} \frac{2}{k+1} \leq 2(n - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k=1}^n \frac{1}{k+1} \leq 2(n-1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k+1}^n \frac{1}{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The asymptotic behavior of the harmonic series is &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt;, so the last expression is &amp;lt;math&amp;gt;\Theta(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;br /&gt;
&lt;br /&gt;
If &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; is an array, &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; cannot be decomposed into subsequences. We would liko to avoid the need for additional arrays and copy operations. Instead, the array should be sorted in-place, that is, by swap operations on pairs of elements. The auxiliary procedure, Pivot partitioning by scanning, is designed exactly for that: it permutes the array such that each of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; is a subarray. Then each recursive call of Quicksort operates on a subarray of the input array, which is specified by two index pointers.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=592</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=592"/>
		<updated>2014-10-02T16:43:07Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Complexity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;, and for &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(i,j)&amp;lt;/math&amp;gt; denote the probability that the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and the &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-th elemet of the eventual, sorted sequence are compared throughtout the algorithm. Using this notation, we may rewrite the above summation as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y) = \sum_{i=1}^{n-1} \sum_{j = i+1}^{n} Pr(i,j)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;i &amp;lt; j&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt; S_{ij}&amp;lt;/math&amp;gt; denote the subsequence of the eventual, sorted sequence that starts with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; and ends with &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. The elements &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; are compared if, and only if, &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; is the very first element of &amp;lt;math&amp;gt;S_{ij}&amp;lt;/math&amp;gt; to be chosen as a pivot. The probability of this event is &amp;lt;math&amp;gt;\frac{2}{|S_{ij}|} = \frac{2}{j - i + 1}&amp;lt;/math&amp;gt;, so we obtain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;k := j-i&amp;lt;/math&amp;gt;, this gives&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1} = \sum_{i=1}^{n-1} \sum_{k=1}^{n} \frac{2}{k+1} \leq 2(n - 1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k=1}^n \frac{1}{k+1} \leq 2(n-1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{k+1}^n \frac{1}{k}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The asymptotic behavior of the harmonic series is &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt;, so the last expression is &amp;lt;math&amp;gt;\Theta(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=591</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=591"/>
		<updated>2014-10-02T16:36:26Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Proof: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;, and for &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(i,j)&amp;lt;/math&amp;gt; denote the probability that the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and the &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;-th elemet of the eventual, sorted sequence are compared throughtout the algorithm. Using this notation, we may rewrite the above summation as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y) = \sum_{i=1}^{n-1} \sum_{j = i+1}^{n} Pr(i,j)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For &amp;lt;math&amp;gt;i,j \in \{1,\dots,n\}&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;i &amp;lt; j&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt; S_{ij}&amp;lt;/math&amp;gt; denote the subsequence of the eventual, sorted sequence that starts with &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; and ends with &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;. The elements &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; are compared if, and only if, &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;\#j&amp;lt;/math&amp;gt; is the very first element of &amp;lt;math&amp;gt;S_{ij}&amp;lt;/math&amp;gt; to be chosen as a pivot. The probability of this event is &amp;lt;math&amp;gt;\frac{2}{|S_{ij}|} = \frac{2}{j - i + 1}&amp;lt;/math&amp;gt;, so we obtain&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{i=1}^{n-1} \sum_{j = i+1}^{n} \frac{2}{j-i+1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=590</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=590"/>
		<updated>2014-10-02T16:11:44Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Complexity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
=== Statement: ===&lt;br /&gt;
In the worst case, the complexity is &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
If the pivot rule ensures for some &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; that the lengths of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; are at most &amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; times the size of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;, then it is even &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
If each pivot value is chosen uniformly randomly from members of the respective sequence and if all selections of pivot values are stochastically independent, the average-case complexity is &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
First note that the complexity for a single recursive call on &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; (disregarding the complexity for the recursive descents on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;gt;) is in &amp;lt;mathO(|S|)&amp;lt;/math&amp;gt;. On each recursive level, all calls are on distinct subsets of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. Therefore, the number of recursive calls with non-empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. The number of calls with empty sequences on one level is at most twice the total number of calls with non-empty sequences on the previous level. Hence, the number of calls with empty sequences on one recursive level is in &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt; as well. In summary, the total complexity on a recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. So, for the total complexity, it remains to estimate the number of recursive levels.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now consider the first statement. The recursion variant implies that the deepest recursive level is &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;. This gives the claimed &amp;lt;math&amp;gt;O(n^2)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Next assume there is a fixed &amp;lt;math&amp;gt;\alpha &amp;lt; 1&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;|S_1| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;|S_3| \leq \alpha \cdot|S|&amp;lt;/math&amp;gt; is guaranteed in each recursive call. Then the length of any sequence on recursive level &amp;lt;math&amp;gt;\#i&amp;lt;/math&amp;gt; is at most &amp;lt;math&amp;gt;\alpha ^ i \cdot |S|&amp;lt;/math&amp;gt;. Therefore, the maximal recursive depth is &amp;lt;math&amp;gt;\lceil \log_{a-1}(n)\rceil&amp;lt;/math&amp;gt;. Since &amp;lt;math&amp;gt;\alpha^{-1} &amp;gt; 1&amp;lt;/math&amp;gt;, the total complexity is in &amp;lt;math&amp;gt;O(n \log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the last statement, the average-case analysis, first note that the number of comparisons alone has the same asymptotic complexity as the algorithm as a whole. Next note that any &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt; are compared at most once througout the entire algorithm: if, and only if,&amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; is chosen as the pivot value for a subsequence to which both elements belong. For &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;Pr(x,y)&amp;lt;/math&amp;gt; denote the probability that and are indeed compared. Since comparison events are distinct and &amp;lt;math&amp;gt;Pr(x,y \in \{0,1\}&amp;lt;/math&amp;gt; for all &amp;lt;math&amp;gt;x,y \in S&amp;lt;/math&amp;gt;, the [[Expected value|expected number]] of comparisons is&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\sum_{x,y \in S, x \neq y} Pr(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;n := |S|&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=589</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=589"/>
		<updated>2014-10-02T15:33:42Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Correctness: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, respectively. In particular &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt; is a permutation of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;. To see that this permutation is sorted, let &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; be two memebers of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; immediately succeeds &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; in the resulting sequence &amp;lt;math&amp;gt;S_1' \| S_2 \| S_3'&amp;lt;/math&amp;gt;. We have to show &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;x,y \in S_1'&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;x,y \in S_3'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; resultes from the induction hypothesis.&lt;br /&gt;
# On the other hand, if &amp;lt;math&amp;gt;x,y \in S_2&amp;lt;/math&amp;gt;. It is &amp;lt;math&amp;gt;x = y = p&amp;lt;/math&amp;gt;, which trivially implies &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt;&lt;br /&gt;
# Finally, for following cases, &amp;lt;math&amp;gt;x \leq y&amp;lt;/math&amp;gt; is implied by the specific way of partitioning &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;:&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;x \in S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;y \in S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, this case distinction covers all potential cases, so the claim is proved.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=588</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=588"/>
		<updated>2014-10-02T13:57:07Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Correctness: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
By incuction hypothesis, &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt; are sorted permutations of &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=587</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=587"/>
		<updated>2014-10-02T13:50:35Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Implementation: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# Chose &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; according to some pivoting rule.&lt;br /&gt;
# &amp;lt;math&amp;gt;S_1 := S_2 := S_3 := \emptyset&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For &amp;lt;math&amp;gt;x \in S&amp;lt;/math&amp;gt;, append &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; to&lt;br /&gt;
## &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt;,&lt;br /&gt;
## &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_1'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Call Quicksort on &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; giving &amp;lt;math&amp;gt;S_3'&amp;lt;/math&amp;gt;&lt;br /&gt;
# Return &amp;lt;math&amp;gt;S_1' \| S_2' \| S_3'&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=586</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=586"/>
		<updated>2014-10-02T13:42:11Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Abstract view: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Choose a pivot value &amp;lt;math&amp;gt;p \in [min\{x|x \in S\},\dots,max\{x|x \in S\}]&amp;lt;/math&amp;gt; (note that &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is not required to be an element of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Partition &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; into sequences, &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt;, such that &amp;lt;math&amp;gt;x &amp;lt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x = p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_2&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;x &amp;gt; p&amp;lt;/math&amp;gt; for &amp;lt;math&amp;gt;x \in S_3&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Sort &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S_3&amp;lt;/math&amp;gt; recursively.&lt;br /&gt;
# The concatenation of all three lists, &amp;lt;math&amp;gt;S_1 \| S_2 \| S_3&amp;lt;/math&amp;gt;, is the result of the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=584</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=584"/>
		<updated>2014-10-02T13:31:43Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=583</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=583"/>
		<updated>2014-10-02T13:31:19Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction Step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=582</id>
		<title>Quicksort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Quicksort&amp;diff=582"/>
		<updated>2014-10-02T13:26:39Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Sorting Algorithms]]&lt;br /&gt;
[[Category:Divide and Conquer]]&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Quick Sort&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;whatever&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[https://openlearnware.tu-darmstadt.de/#!/resource/quick-sort-1945 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' recursion&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After a recursive call, the input sequence of this recursive call is sorted.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' In each recursive call, the sequence of the callee is strictly shorter than that of the caller.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' The sequence is empty or a singleton.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do on an empty sequence or a singleton.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Ditto.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Empty sequences and singletons are trivially sorted.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubble&amp;diff=581</id>
		<title>Bubble</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubble&amp;diff=581"/>
		<updated>2014-10-02T13:20:57Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Algorithm]]&lt;br /&gt;
[[Category:Auxiliary Algorithm]]&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic problem:''' Moving the maximum element&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations, the element at position &amp;lt;math&amp;gt;l + i&amp;lt;/math&amp;gt; is the maximum of the elements at the position &amp;lt;math&amp;gt;l,\dots,l+i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i = r - l&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Exchagne the elements at positions &amp;lt;math&amp;gt;l + i -1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;l + i&amp;lt;/math&amp;gt; if necessary.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' If &amp;lt;math&amp;gt;S[l+i-1] &amp;gt; S[l+i]&amp;lt;/math&amp;gt;, swap &amp;lt;math&amp;gt;S[l+i-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[l+i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' The induction hypothesis implies that, immediately before the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration, &amp;lt;math&amp;gt;S[l+i-1]&amp;lt;/math&amp;gt; is the maximum of the elements at the positions &amp;lt;math&amp;gt;l,\dots,l+i-1&amp;lt;/math&amp;gt;. If &amp;lt;math&amp;gt;S[l+i-1] &amp;gt; S[l+i]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;S[l+i-1]&amp;lt;/math&amp;gt; is also the maximum out of &amp;lt;math&amp;gt;1,\dots,l+i&amp;lt;/math&amp;gt; and should thus be moved to the position &amp;lt;math&amp;gt;l+i&amp;lt;/math&amp;gt;. Otherwise &amp;lt;math&amp;gt;S[l+i]&amp;lt;/math&amp;gt; is at least as large as all elements at positions &amp;lt;math&amp;gt;l+1,\dots,l+i-1&amp;lt;/math&amp;gt; and should thus stay at position &amp;lt;math&amp;gt;l+i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''&lt;br /&gt;
Statement:''' The asymptotic complexity is &amp;lt;math&amp;gt;\Theta(r-l)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
'''&lt;br /&gt;
Proof:''' Obvious.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubble_sort&amp;diff=579</id>
		<title>Bubble sort</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Bubble_sort&amp;diff=579"/>
		<updated>2014-10-02T13:03:06Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Pseudocode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorting based on pairwise comparison]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; iterations, the elements of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; at the positions &amp;lt;math&amp;gt;|S|-i+1,\dots,|S|&amp;lt;/math&amp;gt; are placed at their ocrrect positions in sorting order.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i = |S| -1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Nothing to do.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
'''Abstract view:''' Step-by-step, move the maximum element seen so far to the position &amp;lt;math&amp;gt;|S| - i + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' For &amp;lt;math&amp;gt;j := 2,\dots,|S|-i+1&amp;lt;/math&amp;gt; (in this order). If &amp;lt;math&amp;gt;S[j-1] &amp;gt; S[j]&amp;lt;/math&amp;gt;, swap &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' The loop invariant of the inner loop is this: after &amp;lt;math&amp;gt;m&amp;lt;/math&amp;gt; iterations of the inner loop, &amp;lt;math&amp;gt;S[m+1]&amp;lt;/math&amp;gt; is the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[m+1]&amp;lt;/math&amp;gt;. To see that invariant, note that the induction hypothesis implies for an iteration on index &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; that &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; is the maxiumum out of &amp;lt;math&amp;gt;S[1],\dots,S[j-1]&amp;lt;/math&amp;gt;. So if &amp;lt;math&amp;gt;S[j-1] &amp;gt; S[j]&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; is also the maximum out of &amp;lt;math&amp;gt;S[1],\dots,S[j]&amp;lt;/math&amp;gt;. Therefore, swapping &amp;lt;math&amp;gt;S[j-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt; maintains the invariant. On the other hand, if &amp;lt;math&amp;gt;S[j-1] \leq S[j]&amp;lt;/math&amp;gt;. &amp;lt;math&amp;gt;S[j]&amp;lt;/math&amp;gt; is already the maximum, so doing nothing maintains the invariant in this case.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 BUBBLESORT(''A'')&lt;br /&gt;
 1 '''for''' ''i'' = 1 '''to''' &amp;quot;A.length&amp;quot; - 1 &lt;br /&gt;
 2      '''for''' ''j'' = ''A.length'' '''downto''' ''i'' + 1&lt;br /&gt;
 3            '''if''' ''A''[''j''] &amp;lt; ''A''[''j'' - 1]&lt;br /&gt;
 4                  exchange ''A''[''j''] with ''A''[''j'' - 1]&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statemen:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(n^2)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' The asymptotic complexity of the inner loop in the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th iteration of the outer loop is in &amp;lt;math&amp;gt;\Theta(n - i)&amp;lt;/math&amp;gt;. Therefore, the total complexity is in &amp;lt;math&amp;gt;\Theta \left( \sum_{i=1}^{n-1} (n-i) \right) = \Theta \left( \sum_{i=1}^{n-1} i \right) = \Theta \left( \frac{n(n-1)}{2}\right) = \Theta(n^2)&amp;lt;/math&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert_and_rearrange&amp;diff=571</id>
		<title>B-tree: insert and rearrange</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert_and_rearrange&amp;diff=571"/>
		<updated>2014-10-02T11:46:16Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Text here]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' Text&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' &lt;br /&gt;
# Three pointers &amp;lt;math&amp;gt;p, p_1, p_2 &amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
# A current key &amp;lt;math&amp;gt; K' \in K&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a node &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; such that the following holds: &lt;br /&gt;
# In the case &amp;lt;math&amp;gt;p.n &amp;lt; 2M&amp;lt;/math&amp;gt;, all implementation invariants of B-trees are maintained if the following &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; can be inserted at some position in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; such that after insertion.&lt;br /&gt;
# In the case &amp;lt;math&amp;gt;p.n = 2M&amp;lt;/math&amp;gt;, imagine that we could extend &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.keys by one more slot (and, consequently, extend .successors by one more slot). Then &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; can be inserted in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; at a position such that - except for the statement about the size of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - all implementation invariants of B-trees are again maintained after insertion.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' The height level of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points is decreased by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;p.N &amp;lt; 2M&amp;lt;/math&amp;gt; or (that is, inclusive-or) &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to the root.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
'''Abstract view:''' &lt;br /&gt;
# &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is set to the input pointer.&lt;br /&gt;
# &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are void initially.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' The requirement on the input pointer immediately implies the invariants.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# If the node is not full, the key can be inserted, and we are done.&lt;br /&gt;
## If the new key is larger than all keys stored in the node, it can be appended.&lt;br /&gt;
## Otherwise, is must override one specific slot. For that, first the contents of this slot and of each slot to its right must be moved one position further right (the corresponding values and successor pointers have to be moved as well). Then the new (key,value)-pair may be safely inserted.&lt;br /&gt;
# On the other hand, if the node is indeed full, the key cannot be inserted. In this case:&lt;br /&gt;
## The current node &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; will be split into two nodes, &amp;lt;math&amp;gt;N_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;N_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
## &amp;lt;math&amp;gt;N_1&amp;lt;/math&amp;gt;  will contain all keys strictly less than the median of { &amp;lt;math&amp;gt;p.keys[1], ... , p.keys[p.n], K'&amp;lt;/math&amp;gt; }&lt;br /&gt;
## Analogously, &amp;lt;math&amp;gt;N_2&amp;lt;/math&amp;gt; will contain all keys strictly greater than the median of { &amp;lt;math&amp;gt;p.keys[1], ... , p.keys[p.n], K'&amp;lt;/math&amp;gt; }.&lt;br /&gt;
## Next we try to&lt;br /&gt;
## If &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; is that median itself, nothing is to be done on the current node.&lt;br /&gt;
## Otherwise, the median of &amp;lt;math&amp;gt;\{p.keys[1], \dots , p.keys[p.n], K'\}&amp;lt;/math&amp;gt;  is in one of the slots of the node. This slot is overridden (by moving the contents of each slot to the right one position further left). The previous contents of this slot is the new &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; . If the current node is the root, which we next try to insert in the predecessor of&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.n = 2M&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.keys[M] &amp;lt; K' &amp;lt; p.keys[M + 1]&amp;lt;/math&amp;gt;, break the iteration and continue the loop.&lt;br /&gt;
## Otherwise: &amp;lt;math&amp;gt; x:= M&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt; K' &amp;lt; p.keys[M]&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt; x:= M+1&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
## Set &amp;lt;math&amp;gt; K'' := p.keys[x]&amp;lt;/math&amp;gt;.&lt;br /&gt;
## For &amp;lt;math&amp;gt; j \in \{x+1, \dots, p.n \}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt; p.keys [j-1]:= p.keys[j] &amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p. successor[j-1]:= p.successors[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt; p.keys[p.n] &amp;lt; K'&amp;lt;/math&amp;gt;, insert the new (key, value)-pair at position &amp;lt;math&amp;gt;p.keys[p.n+1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Otherwise:&lt;br /&gt;
## Let &amp;lt;math&amp;gt;i \in \{ 1, \dots , p.n \} &amp;lt;/math&amp;gt; be minimal subject to &amp;lt;math&amp;gt;K' &amp;lt; p.keys[i]&amp;lt;/math&amp;gt;&lt;br /&gt;
## For &amp;lt;math&amp;gt; j \in \{ p.n, \dots , i \} &amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt; p.keys[j+1]:= p.keys[j]. &amp;lt;/math&amp;gt;&lt;br /&gt;
# If &amp;lt;math&amp;gt; p.n &amp;lt; 2M&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt; p.n:= p.n+1&amp;lt;/math&amp;gt; and terminate the algorithm.&lt;br /&gt;
# Otherwise, set &amp;lt;math&amp;gt;K':= K''&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
Easy to see.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=570</id>
		<title>B-tree: minimum</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=570"/>
		<updated>2014-10-02T11:44:27Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Abstract View */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic Problem:''' &lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' A pointer p of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration:&lt;br /&gt;
# '''''p''''' points to some node '''''N''''' of the B-tree.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' '''''p''''' is redirected from the current node '''''N''''' to the first child of the current node.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
# '''''p''''' points to a leaf of the B-tree.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 Minimum(''x'')&lt;br /&gt;
 1 '''while''' leaf(''x'') = false&lt;br /&gt;
 2        ''x'' = c_1(''x'')&lt;br /&gt;
 3 '''return''' key_1(''x'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=569</id>
		<title>B-tree: minimum</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=569"/>
		<updated>2014-10-02T11:42:40Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Pseudocode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic Problem:''' &lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' A pointer p of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 Minimum(''x'')&lt;br /&gt;
 1 '''while''' leaf(''x'') = false&lt;br /&gt;
 2        ''x'' = c_1(''x'')&lt;br /&gt;
 3 '''return''' key_1(''x'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=568</id>
		<title>B-tree: minimum</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=568"/>
		<updated>2014-10-02T11:39:13Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* General Information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic Problem:''' &lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' A pointer p of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 Minimum(x)&lt;br /&gt;
 1 :while leaf(x) = false&lt;br /&gt;
 2 ::x = c1(x)&lt;br /&gt;
 3 :return key1(x)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=567</id>
		<title>B-tree: minimum</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_minimum&amp;diff=567"/>
		<updated>2014-10-02T11:36:51Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General Information ==&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 Minimum(x)&lt;br /&gt;
 1 :while leaf(x) = false&lt;br /&gt;
 2 ::x = c1(x)&lt;br /&gt;
 3 :return key1(x)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=566</id>
		<title>B-tree: merge two siblings</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=566"/>
		<updated>2014-10-02T11:29:14Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction Step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' See [[B-Trees]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisites:''' &lt;br /&gt;
# A node &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; with a key at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; that is not void&lt;br /&gt;
# The number of keys in &amp;lt;math&amp;gt;p.children[k-1]=p.children[k]=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' &lt;br /&gt;
# Three pointers &amp;lt;math&amp;gt;p, p_1, p_2 &amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt; i \ge 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt; p_1&amp;lt;/math&amp;gt; points to the left children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; points to the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;p_1.n = M+i&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; shows on the index of the copied key in &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Assign &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; the left children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; the right children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Move the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Copy the left children of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to the new key in &amp;lt;math&amp;gt;p1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
# Change the number of keys in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1 := p.children[k-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2 := p.children[k]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.children[k] := void&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.keys[M] := p.keys[k]&amp;lt;/math&amp;gt; and for &amp;lt;math&amp;gt;j \in k+1, \dots , p.n&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt; &lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.children[M] := p_2.children[0]&amp;lt;/math&amp;gt;&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt; and set &amp;lt;math&amp;gt;p.n := p.n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
In the induction basic &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are assigned to the left and the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (Invariant 1). The key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; is shifted to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;. So the elements &amp;lt;math&amp;gt;1 \dots , M&amp;lt;/math&amp;gt; are filled (B-Tree #5). The number of elements in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; is increased by one and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is decreased by one (B-Tree #3). So are in &amp;lt;math&amp;gt;p_1 M&amp;lt;/math&amp;gt; keys (Invariant 2). We removed a key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, but because of the invariant of remove (&amp;lt;math&amp;gt;minM&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;), now we have &amp;lt;math&amp;gt;minM - 1&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; (B-Tree #4). We added the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to the left children (all keys in this children are smaller) on the right side, so the sorting order is correct again (B-Tree #6). The copied children comes from the right children, so all keys in this children are bigger again (B-Tree #7). The copied children come from the same level (&amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are both children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;), so all leaves are on the same level again (B-Tree #8). In the induction basic is no key copied from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; (Invariant 3).&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# If not all keys (and children) of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied, copy the key and children from position &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to position &amp;lt;math&amp;gt;M+i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
===Implementation: ===&lt;br /&gt;
# if &amp;lt;math&amp;gt;i \le M-1&amp;lt;/math&amp;gt; (that is, not all keys of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied):&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.keys[M+i] := p_2.keys[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.children[M+i] := p_2.children[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
In the induction step we copy a key and a children from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;. The copy is in the same order as the elements and on the same level. Implementation invariants #1, #2, #4, #6, #7 and #8 are trivially fulfilled. In step 1.3 we increase &amp;lt;math&amp;gt;p_1.n&amp;lt;/math&amp;gt; by one for each copied element (B-Tree #3).&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' Linear in &amp;lt;math&amp;gt;M-1&amp;lt;/math&amp;gt; steps in the best and worst case&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=565</id>
		<title>B-tree: merge two siblings</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=565"/>
		<updated>2014-10-02T11:28:32Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* General Information */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' See [[B-Trees]]&lt;br /&gt;
&lt;br /&gt;
'''Prerequisites:''' &lt;br /&gt;
# A node &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; with a key at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; that is not void&lt;br /&gt;
# The number of keys in &amp;lt;math&amp;gt;p.children[k-1]=p.children[k]=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' &lt;br /&gt;
# Three pointers &amp;lt;math&amp;gt;p, p_1, p_2 &amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt; i \ge 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt; p_1&amp;lt;/math&amp;gt; points to the left children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; points to the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;p_1.n = M+i&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; shows on the index of the copied key in &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Assign &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; the left children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; the right children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Move the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Copy the left children of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to the new key in &amp;lt;math&amp;gt;p1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
# Change the number of keys in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1 := p.children[k-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2 := p.children[k]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.children[k] := void&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.keys[M] := p.keys[k]&amp;lt;/math&amp;gt; and for &amp;lt;math&amp;gt;j \in k+1, \dots , p.n&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt; &lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.children[M] := p_2.children[0]&amp;lt;/math&amp;gt;&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt; and set &amp;lt;math&amp;gt;p.n := p.n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
In the induction basic &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are assigned to the left and the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (Invariant 1). The key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; is shifted to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;. So the elements &amp;lt;math&amp;gt;1 \dots , M&amp;lt;/math&amp;gt; are filled (B-Tree #5). The number of elements in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; is increased by one and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is decreased by one (B-Tree #3). So are in &amp;lt;math&amp;gt;p_1 M&amp;lt;/math&amp;gt; keys (Invariant 2). We removed a key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, but because of the invariant of remove (&amp;lt;math&amp;gt;minM&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;), now we have &amp;lt;math&amp;gt;minM - 1&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; (B-Tree #4). We added the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to the left children (all keys in this children are smaller) on the right side, so the sorting order is correct again (B-Tree #6). The copied children comes from the right children, so all keys in this children are bigger again (B-Tree #7). The copied children come from the same level (&amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are both children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;), so all leaves are on the same level again (B-Tree #8). In the induction basic is no key copied from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; (Invariant 3).&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
'''Abstract view:'''&lt;br /&gt;
# If not all keys (and children) of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied, copy the key and children from position &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to position &amp;lt;math&amp;gt;M+i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# if &amp;lt;math&amp;gt;i \le M-1&amp;lt;/math&amp;gt; (that is, not all keys of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied):&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.keys[M+i] := p_2.keys[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.children[M+i] := p_2.children[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' In the induction step we copy a key and a children from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;. The copy is in the same order as the elements and on the same level. Implementation invariants #1, #2, #4, #6, #7 and #8 are trivially fulfilled. In step 1.3 we increase &amp;lt;math&amp;gt;p_1.n&amp;lt;/math&amp;gt; by one for each copied element (B-Tree #3).&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' Linear in &amp;lt;math&amp;gt;M-1&amp;lt;/math&amp;gt; steps in the best and worst case&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=564</id>
		<title>B-tree: merge two siblings</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_merge_two_siblings&amp;diff=564"/>
		<updated>2014-10-02T11:28:07Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction Basis */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' See B-Tree&lt;br /&gt;
&lt;br /&gt;
'''Prerequisites:''' &lt;br /&gt;
# A node &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; with a key at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; that is not void&lt;br /&gt;
# The number of keys in &amp;lt;math&amp;gt;p.children[k-1]=p.children[k]=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' &lt;br /&gt;
# Three pointers &amp;lt;math&amp;gt;p, p_1, p_2 &amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' After &amp;lt;math&amp;gt; i \ge 0&amp;lt;/math&amp;gt; iterations:&lt;br /&gt;
# &amp;lt;math&amp;gt; p_1&amp;lt;/math&amp;gt; points to the left children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; points to the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;p_1.n = M+i&amp;lt;/math&amp;gt;.&lt;br /&gt;
# &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; shows on the index of the copied key in &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; increases by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;i=M-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Assign &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; the left children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; the right children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Move the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Copy the left children of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to the new key in &amp;lt;math&amp;gt;p1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;&lt;br /&gt;
# Change the number of keys in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1 := p.children[k-1]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2 := p.children[k]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.children[k] := void&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.keys[M] := p.keys[k]&amp;lt;/math&amp;gt; and for &amp;lt;math&amp;gt;j \in k+1, \dots , p.n&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt; &lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.children[M] := p_2.children[0]&amp;lt;/math&amp;gt;&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt; and set &amp;lt;math&amp;gt;p.n := p.n-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
In the induction basic &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are assigned to the left and the right children of the key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; (Invariant 1). The key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; is shifted to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt;. So the elements &amp;lt;math&amp;gt;1 \dots , M&amp;lt;/math&amp;gt; are filled (B-Tree #5). The number of elements in &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; is increased by one and &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is decreased by one (B-Tree #3). So are in &amp;lt;math&amp;gt;p_1 M&amp;lt;/math&amp;gt; keys (Invariant 2). We removed a key of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, but because of the invariant of remove (&amp;lt;math&amp;gt;minM&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;&amp;lt;/math&amp;gt;), now we have &amp;lt;math&amp;gt;minM - 1&amp;lt;/math&amp;gt; keys in &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; (B-Tree #4). We added the key from &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; to the left children (all keys in this children are smaller) on the right side, so the sorting order is correct again (B-Tree #6). The copied children comes from the right children, so all keys in this children are bigger again (B-Tree #7). The copied children come from the same level (&amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are both children of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;), so all leaves are on the same level again (B-Tree #8). In the induction basic is no key copied from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; (Invariant 3).&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
'''Abstract view:'''&lt;br /&gt;
# If not all keys (and children) of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied, copy the key and children from position &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to position &amp;lt;math&amp;gt;M+i&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# if &amp;lt;math&amp;gt;i \le M-1&amp;lt;/math&amp;gt; (that is, not all keys of &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are copied):&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.keys[M+i] := p_2.keys[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.children[M+i] := p_2.children[i].&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p_1.n := p_1.n+1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Otherwise, terminate the algorithm.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' In the induction step we copy a key and a children from &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt;. The copy is in the same order as the elements and on the same level. Implementation invariants #1, #2, #4, #6, #7 and #8 are trivially fulfilled. In step 1.3 we increase &amp;lt;math&amp;gt;p_1.n&amp;lt;/math&amp;gt; by one for each copied element (B-Tree #3).&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' Linear in &amp;lt;math&amp;gt;M-1&amp;lt;/math&amp;gt; steps in the best and worst case&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert_and_rearrange&amp;diff=563</id>
		<title>B-tree: insert and rearrange</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert_and_rearrange&amp;diff=563"/>
		<updated>2014-10-02T11:27:00Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction Step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Text here]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' Text&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' &lt;br /&gt;
# Three pointers &amp;lt;math&amp;gt;p, p_1, p_2 &amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
# A current key &amp;lt;math&amp;gt; K' \in K&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a node &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; such that the following holds: &lt;br /&gt;
# In the case &amp;lt;math&amp;gt;p.n &amp;lt; 2M&amp;lt;/math&amp;gt;, all implementation invariants of B-trees are maintained if the following &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; can be inserted at some position in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; such that after insertion.&lt;br /&gt;
# In the case &amp;lt;math&amp;gt;p.n = 2M&amp;lt;/math&amp;gt;, imagine that we could extend &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.keys by one more slot (and, consequently, extend .successors by one more slot). Then &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; can be inserted in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; at a position such that - except for the statement about the size of &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; - all implementation invariants of B-trees are again maintained after insertion.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' The height level of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points is decreased by &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;p.N &amp;lt; 2M&amp;lt;/math&amp;gt; or (that is, inclusive-or) &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to the root.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
'''Abstract view:''' &lt;br /&gt;
# &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is set to the input pointer.&lt;br /&gt;
# &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; are void initially.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' The requirement on the input pointer immediately implies the invariants.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# If the node is not full, the key can be inserted, and we are done.&lt;br /&gt;
## If the new key is larger than all keys stored in the node, it can be appended.&lt;br /&gt;
## Otherwise, is must override one specific slot. For that, first the contents of this slot and of each slot to its right must be moved one position further right (the corresponding values and successor pointers have to be moved as well). Then the new (key,value)-pair may be safely inserted.&lt;br /&gt;
# On the other hand, if the node is indeed full, the key cannot be inserted. In this case:&lt;br /&gt;
## The current node &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; will be split into two nodes, &amp;lt;math&amp;gt;N_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;N_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
## &amp;lt;math&amp;gt;N_1&amp;lt;/math&amp;gt;  will contain all keys strictly less than the median of { &amp;lt;math&amp;gt;p.keys[1], ... , p.keys[p.n], K'&amp;lt;/math&amp;gt; }&lt;br /&gt;
## Analogously, &amp;lt;math&amp;gt;N_2&amp;lt;/math&amp;gt; will contain all keys strictly greater than the median of { &amp;lt;math&amp;gt;p.keys[1], ... , p.keys[p.n], K'&amp;lt;/math&amp;gt; }.&lt;br /&gt;
## Next we try to&lt;br /&gt;
## If &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; is that median itself, nothing is to be done on the current node.&lt;br /&gt;
## Otherwise, the median of &amp;lt;math&amp;gt;\{p.keys[1], \dots , p.keys[p.n], K'\}&amp;lt;/math&amp;gt;  is in one of the slots of the node. This slot is overridden (by moving the contents of each slot to the right one position further left). The previous contents of this slot is the new &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; . If the current node is the root, which we next try to insert in the predecessor of&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.n = 2M&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.keys[M] &amp;lt; K' &amp;lt; p.keys[M + 1]&amp;lt;/math&amp;gt;, break the iteration and continue the loop.&lt;br /&gt;
## Otherwise: &amp;lt;math&amp;gt; x:= M&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt; K' &amp;lt; p.keys[M]&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt; x:= M+1&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
## Set &amp;lt;math&amp;gt; K'' := p.keys[x]&amp;lt;/math&amp;gt;.&lt;br /&gt;
## For &amp;lt;math&amp;gt; j \in \{x+1, \dots, p.n \}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt; p.keys [j-1]:= p.keys[j] &amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p. successor[j-1]:= p.successors[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt; p.keys[p.n] &amp;lt; K'&amp;lt;/math&amp;gt;, insert the new (key, value)-pair at position &amp;lt;math&amp;gt;p.keys[p.n+1&amp;lt;/math&amp;gt;&lt;br /&gt;
# Otherwise:&lt;br /&gt;
## Let &amp;lt;math&amp;gt;i \in \{ 1, \dots , p.n \} &amp;lt;/math&amp;gt; be minimal subject to &amp;lt;math&amp;gt;K' &amp;lt; p.keys[i]&amp;lt;/math&amp;gt;&lt;br /&gt;
## For &amp;lt;math&amp;gt; j \in \{ p.n, \dots , i \} &amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt; p.keys[j+1]:= p.keys[j]. &amp;lt;/math&amp;gt;&lt;br /&gt;
# If &amp;lt;math&amp;gt; p.n &amp;lt; 2M&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt; p.n:= p.n+1&amp;lt;/math&amp;gt; and terminate the algorithm.&lt;br /&gt;
# Otherwise, set &amp;lt;math&amp;gt;K':= K''&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
Easy to see.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_find&amp;diff=562</id>
		<title>B-tree: find</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_find&amp;diff=562"/>
		<updated>2014-10-02T11:26:04Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: /* Induction Step */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Find|Sorted sequence: find]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' A pointer '''''p''''' of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration:&lt;br /&gt;
# '''''p''''' points to some node '''''N''''' of the B-tree and&lt;br /&gt;
# the searched key is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' '''''p''''' is redirected from the current node '''''N''''' to some child of the current node.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
# '''''p''''' points to a leaf of the B-tree or (that is, inclusive-or)&lt;br /&gt;
# the searched key is in the node to which '''''p''''' points.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
'''Abstract view:''' '''''p''''' is initialized so as to point to the root of the B-tree.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# Let '''''N''''' denote the node to which '''''p''''' currently points.&lt;br /&gt;
# If the searched key is in '''''N''''', terminate the algorithm and return '''''true'''''.&lt;br /&gt;
# Otherwise, if '''''N''''' is a leaf, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# Otherwise, let '''''p''''' point the child of '''''N''''' such that the searched key is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If '''''K''''' is one of the values &amp;lt;math&amp;gt;p.keys[1],\dots,p.keys[p.n]&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''true'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, the current node is a leaf), terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p := p.children[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, if &amp;lt;math&amp;gt;K &amp;gt; p.keys[p.n]&amp;lt;/math set &amp;lt;math&amp;gt;p := p.children[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, there is exactly one &amp;lt;math&amp;gt;i \in \{1,\dots,p.n-1\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.keys[i] &amp;lt; K &amp;lt; p.keys[i+1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p := p.children[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
Obvious.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-FIND(''x,k'')&lt;br /&gt;
 1 ''i'' = 1&lt;br /&gt;
 2 '''while''' i &amp;amp;le; ''x.n'' and ''k'' &amp;amp;gt; ''x.key&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'' &lt;br /&gt;
 3        ''i'' = ''i'' + 1&lt;br /&gt;
 4 '''if''' ''i'' &amp;amp;le; ''x.n'' and ''k'' == ''x.key&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'' &lt;br /&gt;
 5        '''return''' (''x.i'')&lt;br /&gt;
 6 '''elseif''' '' x.leaf''&lt;br /&gt;
 7        '''return''' NIL&lt;br /&gt;
 8 '''else''' DISK-READ(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'') &lt;br /&gt;
 9        '''return''' B-TREE-FIND(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,k'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the fact that the height of B-tree with '''''n''''' nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees]] page).&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert&amp;diff=561</id>
		<title>B-tree: insert</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert&amp;diff=561"/>
		<updated>2014-10-02T11:19:32Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: B-Tree]]&lt;br /&gt;
[[Category: Algorithm]]&lt;br /&gt;
&lt;br /&gt;
[[Category: Checkup]]&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Insert|Sorted sequence: insert]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' Pointers '''''p''''' and '''''p'''''' of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration:&lt;br /&gt;
&lt;br /&gt;
# '''''p''''' points to some node '''''N''''' of the B-tree such that &amp;lt;math&amp;gt;n &amp;lt; 2M -1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' '''''p''''' is redirected from the current node '''''N''''' to some child of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
Break condition: '''''p''''' points to a leaf.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# If the tree is empty, create a new root with '''''K''''' the only key and terminate the algorithm.&lt;br /&gt;
# Otherwise, '''''p''''' points to the root.&lt;br /&gt;
# If the root is full:&lt;br /&gt;
## A new root is created, and the old root is dhe unique child of the new root.&lt;br /&gt;
## The old root is '''split''' into two siblings.&lt;br /&gt;
## '''''p''''' points to the new root.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If the tree is empty:&lt;br /&gt;
## Create a new, empty node and let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to it.&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p.keys[1] := K&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Terminate the algorithm.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to the root of the tree.&lt;br /&gt;
#If &amp;lt;math&amp;gt;p.n = 2M = 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
## Create a new, empty node and let &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; point to it.&lt;br /&gt;
## Cat &amp;lt;math&amp;gt;p'.children[0] := p&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Call [[B-Trees|B-tree: split node into two siblings]] with pointer &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Set &amp;lt;math&amp;gt; p := p'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Basically, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the insert procedure are fulfilled after the preprocessing.&lt;br /&gt;
&lt;br /&gt;
If the tree is empty or, otherwise, the root is not full, all invariants are trivially fulfilled by Step 1 and Step 2, respectively. So consider the case that the tree is not empty and the root is full, that is, Step 3 is executed.&lt;br /&gt;
&lt;br /&gt;
Implementation invariants #1, #2, and #8 are trivially. Maintenance of the implementation invariants #3-#7 is guaranteed by the split procedure.&lt;br /&gt;
Finally, the loop invariants result from Step 3.4.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If the current node '''''N''''' is a leaf, insert the new key in '''''N''''' and terminate the algorithm.&lt;br /&gt;
# Otherwise, let '''''N'''''' be the child of '''''N''''' such that the key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child (ties arbitrarily broken).&lt;br /&gt;
# If '''''N'''''' is full, '''''N'''''' is '''split''' into two siblings.&lt;br /&gt;
# The new current node is the child of '''''N''''' such that the key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child (one of these two siblings, in fact; ties arbitrarily broken).&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt; K \geq p.keys[p.n]&amp;lt;/math&amp;gt;, insert the key at position &amp;lt;math&amp;gt;p.n + 1&amp;lt;/math&amp;gt;; otherwise:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be the minimal position such that &amp;lt;math&amp;gt;K &amp;lt; p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt;j = p.n,\dots,k&amp;lt;/math&amp;gt; (in that order), set &amp;lt;math&amp;gt;p.keys[j+1] := p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Insert the new key at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p.n := p.n + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Terminate the algorithm.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K \geq p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[k].n = 2M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: split node into two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p := p.children[0]&amp;lt;/math&amp;gt;; otherwise, set &amp;lt;math&amp;gt;p := p.children[k]&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; is maximal such that &amp;lt;math&amp;gt;K \geq p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
Analogously to the induction basis, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the insert procedure are maintained through an iteration of the main loop.&lt;br /&gt;
&lt;br /&gt;
Again, the implementation invariants #1, #2 and #8 are trivially maintained. If the node is not full, the other implementation invariants and the above-mentioned loop invariants of the insert procedure are maintained as well. So consider the case that the node is full.&lt;br /&gt;
&lt;br /&gt;
Analogously to the induction basis, the implementation invariants #3-#7 are the guaranteed by the split operation.&lt;br /&gt;
&lt;br /&gt;
Finally, the loop invariants of the insert procedure result from Step 4&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&lt;br /&gt;
=== B-TREE-INSERT(''T'',''k'') ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-INSERT(''T'',''k'')&lt;br /&gt;
  1 ''r'' = ''T.root''&lt;br /&gt;
  2 '''if''' ''r.n'' == 2''t'' - 1&lt;br /&gt;
  3      ''s'' = ALLOCATE-NODE()&lt;br /&gt;
  4      ''T.root'' = ''s''&lt;br /&gt;
  5      ''s.leaf'' = FALSE&lt;br /&gt;
  6      ''s.n'' = 0&lt;br /&gt;
  7      ''s.c&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;'' = ''r''&lt;br /&gt;
  8      B-TREE-SPLIT-CHILD(''s'', 1)&lt;br /&gt;
  9      B-TREE-INSERT-NONFULL(''s, k'')&lt;br /&gt;
 10 '''else''' B-TREE-INSERT-NONFULL(''r, k'')   &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== B-TREE-INSERT-NONFULL(''x'',''k'') ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-INSERT-NONFULL(''x'',''k'')&lt;br /&gt;
  1 ''i'' = ''x.n''&lt;br /&gt;
  2 '''if''' ''x.leaf''&lt;br /&gt;
  3      '''while''' ''i &amp;amp;ge; 1 and ''k'' &amp;lt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
  4              ''x.key''&amp;lt;sub&amp;gt;i+1&amp;lt;/sub&amp;gt;= ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
  5              ''i'' = ''i'' - 1&lt;br /&gt;
  6      ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;+111 = ''k''&lt;br /&gt;
  7      ''x.n'' = ''x.n'' + 1&lt;br /&gt;
  8      DISK-WRITE(''x)&lt;br /&gt;
  9 '''else while''' ''i'' &amp;amp;ge; 1 and ''k'' &amp;lt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
 10             ''i'' = ''i'' - 1&lt;br /&gt;
 11        ''i'' = ''i'' + 1&lt;br /&gt;
 12        DISK-READ(''x.c''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;)&lt;br /&gt;
 13        '''if''' ''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;.n'' == 2''t'' - 1&lt;br /&gt;
 14               B-TREE-SPLIT-CHILD(''x, i'')&lt;br /&gt;
 15               '''if''' ''k'' &amp;gt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
 16                       ''i'' = ''i'' + 1&lt;br /&gt;
 17         B-TREE-INSERT-NONFULL(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;, k)   &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the facts that&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is assumed to be fixed, and&lt;br /&gt;
# the height of a B-tree with &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees|B-tree]] page).&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;br /&gt;
In the above specification, each full node is split into two when visited. This is done for precautionary reasons only. With a slight modification, this can be avoided: when the leaf is reached, go back along the traversed path and split full nodes until the first non-full node is reached. Evidently, this reduces the number of splits. However, chances are high that these nodes have to be split sooner or later, so the true benefit is not clear. The version presented here has primarily been selected because its loop invariant is simpler and more intuitive.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert&amp;diff=560</id>
		<title>B-tree: insert</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_insert&amp;diff=560"/>
		<updated>2014-10-02T11:18:55Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: B-Tree]]&lt;br /&gt;
[[Category: Algorithm]]&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Insert|Sorted sequence: insert]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' Pointers '''''p''''' and '''''p'''''' of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration:&lt;br /&gt;
&lt;br /&gt;
# '''''p''''' points to some node '''''N''''' of the B-tree such that &amp;lt;math&amp;gt;n &amp;lt; 2M -1&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' '''''p''''' is redirected from the current node '''''N''''' to some child of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
Break condition: '''''p''''' points to a leaf.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
# If the tree is empty, create a new root with '''''K''''' the only key and terminate the algorithm.&lt;br /&gt;
# Otherwise, '''''p''''' points to the root.&lt;br /&gt;
# If the root is full:&lt;br /&gt;
## A new root is created, and the old root is dhe unique child of the new root.&lt;br /&gt;
## The old root is '''split''' into two siblings.&lt;br /&gt;
## '''''p''''' points to the new root.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If the tree is empty:&lt;br /&gt;
## Create a new, empty node and let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to it.&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p.keys[1] := K&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Terminate the algorithm.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to the root of the tree.&lt;br /&gt;
#If &amp;lt;math&amp;gt;p.n = 2M = 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
## Create a new, empty node and let &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; point to it.&lt;br /&gt;
## Cat &amp;lt;math&amp;gt;p'.children[0] := p&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Call [[B-Trees|B-tree: split node into two siblings]] with pointer &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Set &amp;lt;math&amp;gt; p := p'&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
Basically, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the insert procedure are fulfilled after the preprocessing.&lt;br /&gt;
&lt;br /&gt;
If the tree is empty or, otherwise, the root is not full, all invariants are trivially fulfilled by Step 1 and Step 2, respectively. So consider the case that the tree is not empty and the root is full, that is, Step 3 is executed.&lt;br /&gt;
&lt;br /&gt;
Implementation invariants #1, #2, and #8 are trivially. Maintenance of the implementation invariants #3-#7 is guaranteed by the split procedure.&lt;br /&gt;
Finally, the loop invariants result from Step 3.4.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If the current node '''''N''''' is a leaf, insert the new key in '''''N''''' and terminate the algorithm.&lt;br /&gt;
# Otherwise, let '''''N'''''' be the child of '''''N''''' such that the key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child (ties arbitrarily broken).&lt;br /&gt;
# If '''''N'''''' is full, '''''N'''''' is '''split''' into two siblings.&lt;br /&gt;
# The new current node is the child of '''''N''''' such that the key to be inserted is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child (one of these two siblings, in fact; ties arbitrarily broken).&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt; K \geq p.keys[p.n]&amp;lt;/math&amp;gt;, insert the key at position &amp;lt;math&amp;gt;p.n + 1&amp;lt;/math&amp;gt;; otherwise:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be the minimal position such that &amp;lt;math&amp;gt;K &amp;lt; p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt;j = p.n,\dots,k&amp;lt;/math&amp;gt; (in that order), set &amp;lt;math&amp;gt;p.keys[j+1] := p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Insert the new key at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p.n := p.n + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Terminate the algorithm.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K \geq p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[k].n = 2M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: split node into two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p := p.children[0]&amp;lt;/math&amp;gt;; otherwise, set &amp;lt;math&amp;gt;p := p.children[k]&amp;lt;/math&amp;gt; where &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; is maximal such that &amp;lt;math&amp;gt;K \geq p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
Analogously to the induction basis, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the insert procedure are maintained through an iteration of the main loop.&lt;br /&gt;
&lt;br /&gt;
Again, the implementation invariants #1, #2 and #8 are trivially maintained. If the node is not full, the other implementation invariants and the above-mentioned loop invariants of the insert procedure are maintained as well. So consider the case that the node is full.&lt;br /&gt;
&lt;br /&gt;
Analogously to the induction basis, the implementation invariants #3-#7 are the guaranteed by the split operation.&lt;br /&gt;
&lt;br /&gt;
Finally, the loop invariants of the insert procedure result from Step 4&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
&lt;br /&gt;
=== B-TREE-INSERT(''T'',''k'') ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-INSERT(''T'',''k'')&lt;br /&gt;
  1 ''r'' = ''T.root''&lt;br /&gt;
  2 '''if''' ''r.n'' == 2''t'' - 1&lt;br /&gt;
  3      ''s'' = ALLOCATE-NODE()&lt;br /&gt;
  4      ''T.root'' = ''s''&lt;br /&gt;
  5      ''s.leaf'' = FALSE&lt;br /&gt;
  6      ''s.n'' = 0&lt;br /&gt;
  7      ''s.c&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;'' = ''r''&lt;br /&gt;
  8      B-TREE-SPLIT-CHILD(''s'', 1)&lt;br /&gt;
  9      B-TREE-INSERT-NONFULL(''s, k'')&lt;br /&gt;
 10 '''else''' B-TREE-INSERT-NONFULL(''r, k'')   &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== B-TREE-INSERT-NONFULL(''x'',''k'') ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-INSERT-NONFULL(''x'',''k'')&lt;br /&gt;
  1 ''i'' = ''x.n''&lt;br /&gt;
  2 '''if''' ''x.leaf''&lt;br /&gt;
  3      '''while''' ''i &amp;amp;ge; 1 and ''k'' &amp;lt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
  4              ''x.key''&amp;lt;sub&amp;gt;i+1&amp;lt;/sub&amp;gt;= ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
  5              ''i'' = ''i'' - 1&lt;br /&gt;
  6      ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;+111 = ''k''&lt;br /&gt;
  7      ''x.n'' = ''x.n'' + 1&lt;br /&gt;
  8      DISK-WRITE(''x)&lt;br /&gt;
  9 '''else while''' ''i'' &amp;amp;ge; 1 and ''k'' &amp;lt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
 10             ''i'' = ''i'' - 1&lt;br /&gt;
 11        ''i'' = ''i'' + 1&lt;br /&gt;
 12        DISK-READ(''x.c''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;)&lt;br /&gt;
 13        '''if''' ''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;.n'' == 2''t'' - 1&lt;br /&gt;
 14               B-TREE-SPLIT-CHILD(''x, i'')&lt;br /&gt;
 15               '''if''' ''k'' &amp;gt; ''x.key''&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;&lt;br /&gt;
 16                       ''i'' = ''i'' + 1&lt;br /&gt;
 17         B-TREE-INSERT-NONFULL(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;, k)   &lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the facts that&lt;br /&gt;
&lt;br /&gt;
# &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is assumed to be fixed, and&lt;br /&gt;
# the height of a B-tree with &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees|B-tree]] page).&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;br /&gt;
In the above specification, each full node is split into two when visited. This is done for precautionary reasons only. With a slight modification, this can be avoided: when the leaf is reached, go back along the traversed path and split full nodes until the first non-full node is reached. Evidently, this reduces the number of splits. However, chances are high that these nodes have to be split sooner or later, so the true benefit is not clear. The version presented here has primarily been selected because its loop invariant is simpler and more intuitive.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree&amp;diff=498</id>
		<title>Binary search tree</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree&amp;diff=498"/>
		<updated>2014-10-01T06:31:47Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Data Structures]]&lt;br /&gt;
[[Category:Trees]]&lt;br /&gt;
[[Category:Binary_Search_Tree]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;plainlinks&amp;quot; style=&amp;quot;float:right;margin:0 0 5px 5px; border:1px solid #AAAAAA; width:auto; padding:1em; margin: 0px 0px 1em 1em;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.8em;font-weight:bold;text-align: center;margin:0.2em 0 1em 0&amp;quot;&amp;gt;Binary Search Tree&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 1em 0; text-align:center&amp;quot;&amp;gt;[[Sorted sequence]]&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size: 1.2em; margin:.5em 0 .5em 0;text-align:center&amp;quot;&amp;gt;[[File:olw_logo1.png|20px]][https://openlearnware.tu-darmstadt.de/#!/resource/binary-search-tree-1938 Openlearnware]&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
''' Abstract data structure:'''&lt;br /&gt;
[[Sorted sequence]]&lt;br /&gt;
&lt;br /&gt;
'''Implementation invariant:'''&lt;br /&gt;
&lt;br /&gt;
# There is a tree item type with three components:&lt;br /&gt;
## '''''key''''' is of generic type &amp;lt;math&amp;gt;\kappa&amp;lt;/math&amp;gt;&lt;br /&gt;
## '''''left''''' and '''''right''''' of type &amp;quot;pointer to tree item of type &amp;lt;math&amp;gt;\kappa&amp;lt;/math&amp;gt;&amp;quot;&lt;br /&gt;
# An object of the binary search tree type contains a pointer '''''root''''' of type &amp;quot;pointer to tree item of type &amp;lt;math&amp;gt;\kappa&amp;lt;/math&amp;gt;&amp;quot;&lt;br /&gt;
# The pointer '''''root''''' points to a well-formed binary search tree. In accordance with the definition of [[Directed Tree|directed trees]], &amp;quot;well-formed&amp;quot; means that, for any node, there is exactly one [[path]] from the root to that node.&lt;br /&gt;
&lt;br /&gt;
== Remark ==&lt;br /&gt;
* Besides the methos of [[Sorted sequence|sorted sequences]], binary search trees have a private method [[Binary Search Tree:Remove node]], which receives a pointer '''''p''''' to a binary search tree node and removes id (possibly by removeing another node and overwriting the key to be removed with the key of the other node. Prerequisite: &amp;lt;math&amp;gt; p.left \neq void&amp;lt;/math&amp;gt;&lt;br /&gt;
* There are variants on binary search trees, such as [http://en.wikipedia.org/wiki/AVL_tree AVL trees] and [http://en.wikipedia.org/wiki/Red_black_tree red-black-trees], for which the height of the tree is guaranteed to be in &amp;lt;math&amp;gt;O \log{n}&amp;lt;/math&amp;gt; in these variants (because the additional operations in these methods are necessary to maintain logatihmic height are linear in the height of the tree as well=.&lt;br /&gt;
* For further information, see section &amp;quot;Binary search tree&amp;quot; of page [[Directed Tree]].&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Main_Page&amp;diff=497</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Main_Page&amp;diff=497"/>
		<updated>2014-10-01T06:27:24Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News ==&lt;br /&gt;
* &amp;lt;math&amp;gt;LaTeX&amp;lt;/math&amp;gt; [http://www.mediawiki.org/wiki/Manual:Math available now!]&lt;br /&gt;
* ToDo List added&lt;br /&gt;
* Every content has to be in English!&lt;br /&gt;
* [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi Syntaxhighlight]&lt;br /&gt;
&lt;br /&gt;
== Rules ==&lt;br /&gt;
* Add finalized reconstructions of the old Wiki to Category:Checkup.&lt;br /&gt;
* Don't any non-Weihe content until the reconstructions isn't finished.&lt;br /&gt;
* Keep your active reconstructing Pages in &amp;quot;Division of labor&amp;quot; section up to date!&lt;br /&gt;
&lt;br /&gt;
== Divison of labor ==&lt;br /&gt;
* Fabio Cuozzo - Heaps&lt;br /&gt;
* Daniel Kratschmann - Problems&lt;br /&gt;
* Jan Hohmann - B-Tree&lt;br /&gt;
* Jan Rathjens - Ford-Fulkerson&lt;br /&gt;
* Thomas Lautenschläger - ???&lt;br /&gt;
&lt;br /&gt;
== Page Status ==&lt;br /&gt;
Final: [[:Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
=== Notations ===&lt;br /&gt;
* [[Asymptotic notation]]&lt;br /&gt;
* [[L' Hospital]]&lt;br /&gt;
* [[Master theorem]]&lt;br /&gt;
=== Problems ===&lt;br /&gt;
* [[Maximum matching problem]]&lt;br /&gt;
* [[Max-Flow Problems]]&lt;br /&gt;
* [[Min-Cost Flow Problems]]&lt;br /&gt;
* [[Shortest Paths Problems]]&lt;br /&gt;
** [[All pairs shortest paths]]&lt;br /&gt;
*** [[Floyd-Warshall]]&lt;br /&gt;
*** [[Bellman-Ford]]&lt;br /&gt;
*** [[Shortest paths by repeated squaring]] (variant of Bellman-Ford) &lt;br /&gt;
** [[Single source shortest paths]]&lt;br /&gt;
*** [[Dijkstra]]&lt;br /&gt;
** [[Single source single target shortest paths]]&lt;br /&gt;
*** [[A*]]&lt;br /&gt;
* [[Maximum spanning forest]]&lt;br /&gt;
* [[Problems on Sequences]]&lt;br /&gt;
** [[Basic Problems on Sequences]]&lt;br /&gt;
*** [[Find an element in a sequence]]&lt;br /&gt;
*** [[Insert an element in a sequence]]&lt;br /&gt;
*** [[Median]]&lt;br /&gt;
*** [[Merging two sorted sequences]]&lt;br /&gt;
** [[Pattern Matching]]&lt;br /&gt;
*** [[One-dimensional string matching]]&lt;br /&gt;
*** [[String matching]]&lt;br /&gt;
** [[Sorting]]&lt;br /&gt;
*** [[Sorting based on pairwise comparison]]&lt;br /&gt;
*** [[Sorting Sequences of Strings]]&lt;br /&gt;
&lt;br /&gt;
=== Coding Basics ===&lt;br /&gt;
* [[Heritage]]&lt;br /&gt;
* [[Generics]]&lt;br /&gt;
* [[Collections]]&lt;br /&gt;
** [[Iterator]]&lt;br /&gt;
** [[Comparator]]&lt;br /&gt;
&lt;br /&gt;
=== String Matching Algorithms ===&lt;br /&gt;
* [[Simple string matching algorithm]]&lt;br /&gt;
* [[String matching based on finite automaton]]&lt;br /&gt;
&lt;br /&gt;
=== Sorting Algorithms ===&lt;br /&gt;
* [[Bubble]]&lt;br /&gt;
* [[Insertion Sort]]&lt;br /&gt;
* [[Quick Sort]]&lt;br /&gt;
* [[Bubble Sort]]&lt;br /&gt;
* [[Merge Sort]]&lt;br /&gt;
* [[Bucket Sort]]&lt;br /&gt;
* [[Selection Sort]]&lt;br /&gt;
* [[Bogo Sort]]&lt;br /&gt;
&lt;br /&gt;
=== Search Algorithms ===&lt;br /&gt;
* [[Binary Search]]&lt;br /&gt;
&lt;br /&gt;
=== Tree Algorithms ===&lt;br /&gt;
* [[Depth-First Search]]&lt;br /&gt;
* [[Breadth-First Search]]&lt;br /&gt;
* [[B-Tree:Find]]&lt;br /&gt;
* [[B-Tree:Minimum]]&lt;br /&gt;
* [[B-Tree:Maximum]]&lt;br /&gt;
* [[B-Tree:Insert]]&lt;br /&gt;
* [[B-Tree:Insert and Rearrange]]&lt;br /&gt;
* [[B-Tree:merge two Siblings]]&lt;br /&gt;
* [[B-Tree:Remove]]&lt;br /&gt;
* [[B-Tree:Shift Key to Sibling]]&lt;br /&gt;
* [[B-Tree:Rotate]]&lt;br /&gt;
* [[B-Tree:Merge]]&lt;br /&gt;
* [[B-Tree:Split-Child]]&lt;br /&gt;
* [[Binary Search Tree:Find]]&lt;br /&gt;
* [[Binary Search Tree:Minimum]]&lt;br /&gt;
* [[Binary Search Tree:Maximum]]&lt;br /&gt;
* [[Binary Search Tree:Insert]]&lt;br /&gt;
* [[Binary Search Tree:Remove]]&lt;br /&gt;
* [[Binary Search Tree:Remove node]]&lt;br /&gt;
* [[Binary Search Tree:Traverse]]&lt;br /&gt;
&lt;br /&gt;
=== Graph Theory ===&lt;br /&gt;
* [[Directed Graph]]&lt;br /&gt;
* [[Bipartite Graph]]&lt;br /&gt;
* [[k-partite Graph]]&lt;br /&gt;
* [[Negative Paths]]&lt;br /&gt;
&lt;br /&gt;
=== Graph Algorithms ===&lt;br /&gt;
* [[Dijkstra]]&lt;br /&gt;
* [[Kruskal]]&lt;br /&gt;
* [[Prim]]&lt;br /&gt;
* [[Bellman-Ford]]&lt;br /&gt;
* [[Floyd-Warshall]]&lt;br /&gt;
* [[Union Find]]&lt;br /&gt;
* [[A*]]&lt;br /&gt;
* [[Alternating paths algorithm]]&lt;br /&gt;
* [[Johnson]]&lt;br /&gt;
&lt;br /&gt;
=== Flow Algorithms ===&lt;br /&gt;
* [[Ford-Fulkerson]]&lt;br /&gt;
=== Data Structures ===&lt;br /&gt;
* [[Linked List]]&lt;br /&gt;
* [[Array List]]&lt;br /&gt;
* [[First In - First Out]]&lt;br /&gt;
* [[First In - Ieast Out]]&lt;br /&gt;
* [[Double Linked List]]&lt;br /&gt;
* [[Heaps]] (DONE (Heap as Array))&lt;br /&gt;
* [[Min-Max Heaps]]&lt;br /&gt;
* [[Hash Table]]&lt;br /&gt;
* [[Directed Tree]]&lt;br /&gt;
* [[Binary Search Tree]]&lt;br /&gt;
* [[B-Trees]]&lt;br /&gt;
* [[Decision Tree]]&lt;br /&gt;
* [[Red-Black Tree]]&lt;br /&gt;
* [[Graphs]]&lt;br /&gt;
&lt;br /&gt;
=== Other Algorithms (LOCKED) ===&lt;br /&gt;
* [[B*]]&lt;br /&gt;
* [[Cyclic Redundancy Check]]&lt;br /&gt;
* [[Eulcid]]&lt;br /&gt;
* [[Gauss]]&lt;br /&gt;
* [[Discrete Fourier transform]]&lt;br /&gt;
* [[Fast Fourier transform]]&lt;br /&gt;
* [[Bresenham]]&lt;br /&gt;
* [[Round Robin]]&lt;br /&gt;
* [[Seperate and Conquer]]&lt;br /&gt;
* [[Message-Digest Algorithm]]&lt;br /&gt;
* [[Secure Hash Algorithm]]&lt;br /&gt;
* [[Sequent calculus]]&lt;br /&gt;
* [[Resolution calculus]]&lt;br /&gt;
* [[Cocke-Younger-Kasami Algorithm]]&lt;br /&gt;
* [[Distance Vector Routing]]&lt;br /&gt;
* [[Link State Round]]&lt;br /&gt;
* [[Z Buffer Algorithm]]&lt;br /&gt;
* [[Marching Squares]]&lt;br /&gt;
* [[Marching Cubes]]&lt;br /&gt;
* [[Bottom-Up Heapsort]]&lt;br /&gt;
* [[Radixsort]]&lt;br /&gt;
* [[Median Cut]]&lt;br /&gt;
* [[Pancake sorting]]&lt;br /&gt;
* [[Karnaugh-Veitch Diagramm]]&lt;br /&gt;
* [[Delanuay Triangulation]]&lt;br /&gt;
* [[Backtracking]]&lt;br /&gt;
* [[Alpha–beta pruning]]&lt;br /&gt;
* [[Beam search]]&lt;br /&gt;
* [[Best-first search]]&lt;br /&gt;
* [[Bidirectional search]]&lt;br /&gt;
* [[Borůvka's algorithm]]&lt;br /&gt;
* [[Branch and bound]]&lt;br /&gt;
* [[D*]]&lt;br /&gt;
* [[Depth-limited search]]&lt;br /&gt;
* [[Edmonds' algorithm]]&lt;br /&gt;
* [[Fringe search]]&lt;br /&gt;
* [[Hill climbing]]&lt;br /&gt;
* [[IDA*]]&lt;br /&gt;
* [[Iterative deepening depth-first search]]&lt;br /&gt;
* [[Jump point search]]&lt;br /&gt;
* [[Lexicographic breadth-first search]]&lt;br /&gt;
* [[SMA*]]&lt;br /&gt;
* [[Uniform-cost search]]&lt;br /&gt;
&lt;br /&gt;
=== Other Data Structures (LOCKED) ===&lt;br /&gt;
* [[Adelson-Velskii and Landis' tree]]&lt;br /&gt;
* [[Patricia-Trie]]&lt;br /&gt;
* [[Suffix Tree]]&lt;br /&gt;
* [[Huffmann Tree]]&lt;br /&gt;
* [[Binary Expression Tree]]&lt;br /&gt;
* [[Hash Set]]&lt;br /&gt;
* [[Incidence Matrix]]&lt;br /&gt;
* [[Voronoi Diagramm]]&lt;br /&gt;
* [[Quad Tree]]&lt;br /&gt;
* [[Oct Tree]]&lt;br /&gt;
* [[kd Tree]]&lt;br /&gt;
* [[Binary space partitioning]]&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree:_remove&amp;diff=496</id>
		<title>Binary search tree: remove</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Binary_search_tree:_remove&amp;diff=496"/>
		<updated>2014-10-01T06:22:33Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Binary Search Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
&lt;br /&gt;
'''Algorithmic Problem:''' [[Sorted Sequence:remove]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''  A pointer '''''p''''' of type &amp;quot;pointer to binary search tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract view ==&lt;br /&gt;
'''Invariant''' After &amp;lt;math&amp;gt;i \geq 0&amp;lt;/math&amp;gt; interations:&lt;br /&gt;
# The pointer '''''p''''' points to a tree node '''''v''''' on height level '''''i'''''.&lt;br /&gt;
# The key '''''K''''' is in [[Directed Tree#Ranges of Search Tree Nodes|range]] of '''''p''''', but &amp;lt;math&amp;gt;p.key \neq K&amp;lt;/math&amp;gt;.&lt;br /&gt;
'''Variant:''' '''''i''''' increased by '''''1'''''.&lt;br /&gt;
&lt;br /&gt;
'''Break Condition:''' One of the following two conditions is fulfilled:&lt;br /&gt;
# It is &amp;lt;math&amp;gt;K &amp;lt; p.key&amp;lt;/math&amp;gt; and either &amp;lt;math&amp;gt;p.left = void&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;p.left.key = K&amp;lt;/math&amp;gt;.&lt;br /&gt;
# It is &amp;lt;math&amp;gt;K &amp;gt; p.key&amp;lt;/math&amp;gt; and either &amp;lt;math&amp;gt;p.right = void&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;p.right.key = K&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Induction basis==&lt;br /&gt;
'''Abstract view:'''&lt;br /&gt;
# If the root contains '''''K''''', remove this occurrence of '''''K'''''. &lt;br /&gt;
# Otherwise, initialize '''''p''''' so as to point to the root.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# If &amp;lt;math&amp;gt;root.key = K&amp;lt;/math&amp;gt;:&lt;br /&gt;
## If &amp;lt;math&amp;gt;root.left = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;root := root.right&amp;lt;/math&amp;gt;&lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;root.right = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;root := root.left&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Otherwise, call method [[Binary Search Tree:remove node|remove node]] with pointer '''''root'''''. &lt;br /&gt;
## Terminate the algorithm and return '''''true'''''. &lt;br /&gt;
&lt;br /&gt;
# Otherwise set &amp;lt;math&amp;gt;p := root&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Induction step==&lt;br /&gt;
'''Abstract View:'''&lt;br /&gt;
# If the next node where to go does not exist or contains '''''K''''', terminate the algorithm (and in the latter case, remove that node appropriately). &lt;br /&gt;
# Otherwise, descend to that node.&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# I &amp;lt;math&amp;gt;K &amp;lt; p.key&amp;lt;/math&amp;gt;:&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.left = void&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''false'''''. &lt;br /&gt;
## Otherwise if &amp;lt;math&amp;gt;p.left.key = K&amp;lt;/math&amp;gt;:&lt;br /&gt;
### If &amp;lt;math&amp;gt;p.left.left = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p.left := p.left.right&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise, if &amp;lt;math&amp;gt;p.left.right = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p.left := p.left.left&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise, call method [[Binary Search Tree:remove node|remove node]] with pointer '''''p.left'''''. &lt;br /&gt;
### Terminate the algorithm and return '''''true'''''. &lt;br /&gt;
## Otherwise (that is, &amp;lt;math&amp;gt;p.left \neq void&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.left.key \neq K&amp;lt;/math&amp;gt;), set &amp;lt;math&amp;gt;p := p.left&amp;lt;/math&amp;gt;. &lt;br /&gt;
# Otherwise (that is, &amp;lt;math&amp;gt;K &amp;gt; p.key&amp;lt;/math&amp;gt;): &lt;br /&gt;
## If &amp;lt;math&amp;gt;p.right = void&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''false'''''. &lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;p.right.key = K&amp;lt;/math&amp;gt;: &lt;br /&gt;
### If &amp;lt;math&amp;gt;p.right.left = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p.right = p.right.right&amp;lt;/math&amp;gt;. &lt;br /&gt;
### Otherwise, if &amp;lt;math&amp;gt;p.right.right = void&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p.right = p.right.left&amp;lt;/math&amp;gt;. &lt;br /&gt;
### Otherwise, call method [[Binary Search Tree:remove node|remove node]] with pointer '''''p.right'''''. &lt;br /&gt;
### Terminate the algorithm and return '''''true'''''. &lt;br /&gt;
## Otherwise (that is, &amp;lt;math&amp;gt;p.right \neq void&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.right.key \neq K&amp;lt;/math&amp;gt;), set &amp;lt;math&amp;gt;p:= p.right&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' Nothing to show.&lt;br /&gt;
&lt;br /&gt;
== Pseudocode ==&lt;br /&gt;
TREE-DELETE(T,z)&lt;br /&gt;
:if left[z] = NULL or right[z] = NULL&lt;br /&gt;
::then y = z&lt;br /&gt;
::else y = TREE-SUCCESSOR(z)&lt;br /&gt;
:if left[y] ≠ NULL&lt;br /&gt;
::then x = left[y]&lt;br /&gt;
::else x = right[y]&lt;br /&gt;
:if x ≠ NULL&lt;br /&gt;
::then p[x] = p [y]&lt;br /&gt;
:if p[y] = NULL&lt;br /&gt;
::then root[T] = x&lt;br /&gt;
::else if y = left[p[y]]&lt;br /&gt;
:::then left[p[y]] = x&lt;br /&gt;
:::else right[p[y]] = x&lt;br /&gt;
:if y ≠ z&lt;br /&gt;
::then key[z] = key[y]&lt;br /&gt;
:::copy y's satellite data into z&lt;br /&gt;
:return y&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Complexity==&lt;br /&gt;
'''Statement:''' Linear in the length of the sequence in the worst case (more precisely, linear in the height of the tree).&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Directed_Tree&amp;diff=495</id>
		<title>Directed Tree</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=Directed_Tree&amp;diff=495"/>
		<updated>2014-10-01T06:20:34Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Background]]&lt;br /&gt;
&lt;br /&gt;
= Definitions =&lt;br /&gt;
# A '''directed tree''' is a directed graph &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; with a designated node &amp;lt;math&amp;gt;r \in V&amp;lt;/math&amp;gt;, the '''root''', such that for each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;, there is exactly one path from &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; in &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;.&lt;br /&gt;
# A directed tree &amp;lt;math&amp;gt; T = (V,A)&amp;lt;/math&amp;gt; is called '''binary''' if each node's outdegree is at most &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The '''subtree''' of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; '''rooted''' at &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; is the subgraph induced by all nodes that are reachable from &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; via paths in &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; (including &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;). In particular, &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; is the subtree of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; rooted at &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For an arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; in a directed tree, &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; is a '''child''' of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is the (unique) '''parent''' of &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The '''height level''' of a node in a directed tree is recursivley defined as follows:&lt;br /&gt;
## The height level of the root is &amp;lt;math&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
## The height level of any other node is one more than the height level of its parent.&lt;br /&gt;
# The '''height''' of an empty tree is &amp;lt;math&amp;gt;-1&amp;lt;/math&amp;gt;. For a non-empty tree, the '''height''' of the tree is the maximum height level of all of its nodes.&lt;br /&gt;
&lt;br /&gt;
= Binary Search Tree =&lt;br /&gt;
&lt;br /&gt;
A '''binary search tree''' is a binary tree &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; such that:&lt;br /&gt;
&lt;br /&gt;
# The outgoing arcs of a node are labeled: at most one is labeled '''left''', at most one is labeled '''right'''.We speak of '''the''' left and '''the''' right arc of a node, respectively.&lt;br /&gt;
# Associated with &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;, there is a '''key type''' &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt; and a [[Genericity|comparison]] on &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; is assigned a value &amp;lt;math&amp;gt;K_v \in \Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
# For an arc &amp;lt;math&amp;gt;(v,w) \in A&amp;lt;/math&amp;gt;, the following holds:&lt;br /&gt;
## If &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; is the left arc of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;K \leq K_v&amp;lt;/math&amp;gt; for all keys &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; (incl. &amp;lt;math&amp;gt;K_w&amp;lt;/math&amp;gt;).&lt;br /&gt;
## If &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; is the right arc of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;K \geq K_v&amp;lt;/math&amp;gt; for all keys &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; (incl. &amp;lt;math&amp;gt;K_w&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
= Multi-way Search Trees =&lt;br /&gt;
&lt;br /&gt;
A '''multi-way search tree''' is a directed tree &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; such that:&lt;br /&gt;
&lt;br /&gt;
# Associated with &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;, there is a '''key type''' &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt; and a [[Genericity|comparison]] on &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Each node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; is assigned a non-empty multiset &amp;lt;math&amp;gt;S_v \subseteq \Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Consider a node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt; and let &amp;lt;math&amp;gt;d_v&amp;lt;/math&amp;gt; denote &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;'s outdegree. If &amp;lt;math&amp;gt;d_v &amp;gt; 0&amp;lt;/math&amp;gt;, it is &amp;lt;math&amp;gt;|S_v| = d_v - 1&amp;lt;/math&amp;gt;; otherwise, &amp;lt;math&amp;gt;|S_v|&amp;lt;/math&amp;gt; may be arbitrary.&lt;br /&gt;
# For &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;, the outgoing arcs of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; are ordered and assigned positions numbered &amp;lt;math&amp;gt;0,\dots,|S_v|&amp;lt;/math&amp;gt;. For the outgoing arc &amp;lt;math&amp;gt;(v,w) \in A&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;i \in \{0,\dots,|S_v|\}&amp;lt;/math&amp;gt; and any &amp;lt;math&amp;gt;K \in S_w&amp;lt;/math&amp;gt;, it is&lt;br /&gt;
## &amp;lt;math&amp;gt;K \geq K'&amp;lt;/math&amp;gt; for at least &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; elements &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;S_v&amp;lt;/math&amp;gt; and&lt;br /&gt;
## &amp;lt;math&amp;gt;K \leq K'&amp;lt;/math&amp;gt; for at least &amp;lt;math&amp;gt;|S_v| - i&amp;lt;/math&amp;gt; elements &amp;lt;math&amp;gt;K'&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;S_v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Ranges of Search Tree Nodes =&lt;br /&gt;
Let &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; be a search tree with root &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt;. The '''range''' of a node is defined recursively:&lt;br /&gt;
# First let &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; be a binary tree:&lt;br /&gt;
## The range of &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Let &amp;lt;math&amp;gt;u \in V&amp;lt;/math&amp;gt;. If existing, let &amp;lt;math&amp;gt;(u,v)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;(u,v)&amp;lt;/math&amp;gt; denote the left and right arc of &amp;lt;math&amp;gt;u&amp;lt;/math&amp;gt;, respectively. The ranges &amp;lt;math&amp;gt;R_v&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;R_w&amp;lt;/math&amp;gt; of &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; are defined as follows:&lt;br /&gt;
### &amp;lt;math&amp;gt;R_v := R_u \cap \{K \in \Kappa | K \leq K_u\}&amp;lt;/math&amp;gt;&lt;br /&gt;
### &amp;lt;math&amp;gt;R_w := R_u \cap \{K \in \Kappa | K \geq K_u\}&amp;lt;/math&amp;gt;&lt;br /&gt;
# Now let &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; be a mutli-way search tree:&lt;br /&gt;
## Again, the range of &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;\Kappa&amp;lt;/math&amp;gt;.&lt;br /&gt;
## For &amp;lt;math&amp;gt;v \in V\setminus\{r\}&amp;lt;/math&amp;gt;, let &amp;lt;math&amp;gt;w \in V&amp;lt;/math&amp;gt; denote the parent node, and let &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; be the position of &amp;lt;math&amp;gt;(w,v)&amp;lt;/math&amp;gt; in the ordered sequence of outgoing arcs of &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt;. Then the '''range''' of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is&lt;br /&gt;
### &amp;lt;math&amp;gt;R_v := \{K \in R_w | K \leq minS_w\}&amp;lt;/math&amp;gt;, if &amp;lt;math&amp;gt;i = 0&amp;lt;/math&amp;gt;;&lt;br /&gt;
### &amp;lt;math&amp;gt;R_v := \{K \in R_w | K \geq maxS_w\}&amp;lt;/math&amp;gt;, if &amp;lt;math&amp;gt;i = |S_w|&amp;lt;/math&amp;gt;;&lt;br /&gt;
### &amp;lt;math&amp;gt;R_v := \{K \in R_w | K \geq a, K \leq b\}&amp;lt;/math&amp;gt;, otherwise, where &amp;lt;math&amp;gt;a,b \in S_w&amp;lt;/math&amp;gt; are the &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-th and &amp;lt;math&amp;gt;(i + 1)&amp;lt;/math&amp;gt;-st element of &amp;lt;math&amp;gt;S_w&amp;lt;/math&amp;gt; in the sorting order of [[Genericity|comparison]] &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Order of Tree Nodes =&lt;br /&gt;
Let &amp;lt;math&amp;gt;T = (V,A)&amp;lt;/math&amp;gt; be a binary search tree and let &amp;lt;math&amp;gt;S \subseteq \Kappa&amp;lt;/math&amp;gt; denote the set of all key values of all nodes of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
# The '''left-root-right order''' of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; is the (unique) order of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that for every node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;:&lt;br /&gt;
## if the left arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; precede the key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;;&lt;br /&gt;
## if the right arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; succeed to key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The '''left-right-root order''' of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; is the (unique) order of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that for every node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;:&lt;br /&gt;
## if the left arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; precede the key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;;&lt;br /&gt;
## if the right arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; precede the key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
# The '''root-left-right order''' of &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt; is the (unique) order of &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; such that for every node &amp;lt;math&amp;gt;v \in V&amp;lt;/math&amp;gt;:&lt;br /&gt;
## if the left arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; succeed the key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;;&lt;br /&gt;
## if the right arc &amp;lt;math&amp;gt;(v,w)&amp;lt;/math&amp;gt; exists, all keys in the subtree rooted at &amp;lt;math&amp;gt;w&amp;lt;/math&amp;gt; succeed the key of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Remark ===&lt;br /&gt;
The sorted sequence of all keys in a search tree is the left-root-right order.&lt;br /&gt;
&lt;br /&gt;
= Immediate Predecessor and Successor =&lt;br /&gt;
For a node &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; of a binary or multi-way search tree,&lt;br /&gt;
# the '''immediate predecessor''' of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;'s immediate predecessor in left-root-right order (if existing), and&lt;br /&gt;
# the '''immediate successor''' of &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; is &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt;'s immediate successor in left-root-right order (if existing).&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_find&amp;diff=494</id>
		<title>B-tree: find</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_find&amp;diff=494"/>
		<updated>2014-10-01T06:19:41Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Find|Sorted sequence: find]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:''' A pointer '''''p''''' of type &amp;quot;pointer to a B-tree node&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
'''Invariant:''' Before and after each iteration:&lt;br /&gt;
# '''''p''''' points to some node '''''N''''' of the B-tree and&lt;br /&gt;
# the searched key is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of '''''N'''''.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' '''''p''''' is redirected from the current node '''''N''''' to some child of the current node.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:'''&lt;br /&gt;
# '''''p''''' points to a leaf of the B-tree or (that is, inclusive-or)&lt;br /&gt;
# the searched key is in the node to which '''''p''''' points.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
'''Abstract view:''' '''''p''''' is initialized so as to point to the root of the B-tree.&lt;br /&gt;
&lt;br /&gt;
'''Implementation:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Obvious.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
'''Abstract view:'''&lt;br /&gt;
# Let '''''N''''' denote the node to which '''''p''''' currently points.&lt;br /&gt;
# If the searched key is in '''''N''''', terminate the algorithm and return '''''true'''''.&lt;br /&gt;
# Otherwise, if '''''N''''' is a leaf, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# Otherwise, let '''''p''''' point the child of '''''N''''' such that the searched key is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of that child&lt;br /&gt;
&lt;br /&gt;
'''Implementation:'''&lt;br /&gt;
# If '''''K''''' is one of the values &amp;lt;math&amp;gt;p.keys[1],\dots,p.keys[p.n]&amp;lt;/math&amp;gt;, terminate the algorithm and return '''''true'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, the current node is a leaf), terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;K &amp;lt; p.keys[1]&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p := p.children[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, if &amp;lt;math&amp;gt;K &amp;gt; p.keys[p.n]&amp;lt;/math set &amp;lt;math&amp;gt;p := p.children[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Otherwise, there is exactly one &amp;lt;math&amp;gt;i \in \{1,\dots,p.n-1\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.keys[i] &amp;lt; K &amp;lt; p.keys[i+1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
# Set &amp;lt;math&amp;gt;p := p.children[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Correctness:''' Obvious.&lt;br /&gt;
== Pseudocode == &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 B-TREE-FIND(''x,k'')&lt;br /&gt;
 1 ''i'' = 1&lt;br /&gt;
 2 '''while''' i &amp;amp;le; ''x.n'' and ''k'' &amp;amp;gt; ''x.key&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'' &lt;br /&gt;
 3        ''i'' = ''i'' + 1&lt;br /&gt;
 4 '''if''' ''i'' &amp;amp;le; ''x.n'' and ''k'' == ''x.key&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'' &lt;br /&gt;
 5        '''return''' (''x.i'')&lt;br /&gt;
 6 '''elseif''' '' x.leaf''&lt;br /&gt;
 7        '''return''' NIL&lt;br /&gt;
 8 '''else''' DISK-READ(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;'') &lt;br /&gt;
 9        '''return''' B-TREE-FIND(''x.c&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;,k'')&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the fact that the height of B-tree with '''''n''''' nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees]] page).&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_remove&amp;diff=493</id>
		<title>B-tree: remove</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_remove&amp;diff=493"/>
		<updated>2014-10-01T06:19:04Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Remove|Sorted sequence: remove]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
## Pointers, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
## A Boolean variable '''''found''''', which is '''''false''''', in the beginning and set '''''true''''' once the key &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; to be removed is seen.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:'''&lt;br /&gt;
# &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a node of the B-tree.&lt;br /&gt;
# If &amp;lt;math&amp;gt;found = false&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
# It is &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt; if, and only if, &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained at least once in one of the current nodes of previous iterations.&lt;br /&gt;
# If &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; points to a node where &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is currently stored.&lt;br /&gt;
## The [[Directed Tree#Order of Tree Nodes|immediate predecessor]] of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to the root, at least two keys are currently stored in the root; otherwise, at least &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; keys are currently stored in the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is redirected to a node one level deeper.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a leaf.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If the tree is empty, terminate the algorithm and return '''''false'''''&lt;br /&gt;
# The pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is initialized so as to point to the root &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;&lt;br /&gt;
# If &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is a leaf:&lt;br /&gt;
## Remove &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; if contained in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
## If &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is empty now, make the tree empty.&lt;br /&gt;
## Terminate the algorithm and return '''''true''''' if &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; was contained in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, '''''false''''' otherwise.&lt;br /&gt;
# Otherwise, if &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; contains exactly one key and is not a leaf: rearrange the root and its two children appropriately.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# If the tree is empty, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to the root.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, the root is a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in the root, say at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Remove the occurrence of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
### If the root is empty now, make the tree an empty tree.&lt;br /&gt;
### Otherwise (that is, the root is still non-empty):&lt;br /&gt;
#### For &amp;lt;math&amp;gt;j \in \{k+1,\dots,p.n\}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.n = 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[0].n = p.children[1].n = M - 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.key[M] := p.key[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p_1 := p.children[0]&amp;lt;/math&amp;gt; and &amp;lt;/math&amp;gt;p_2 := p.children[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.children[0] := p_1.children[0]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.children[M] := p_2.children[0]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt; j = 1,\dots,M-1&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p.keys[j] := p_1.keys[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p.children[j] := p_1.children[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p.keys[M + j] := p_2.keys[j]&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;p.children[M + j] := p_2.children[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := 2M - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Otherwise:&lt;br /&gt;
### If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;:&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[0].n = M - 1&amp;lt;/math&amp;gt;, call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, index &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;shiftRight = false&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.keys[1] = K&amp;lt;math&amp;gt;, set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;found := true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p := p.children[0]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise (that is, &amp;lt;math&amp;gt;K &amp;gt; p.key[1]&amp;lt;/math&amp;gt;):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[1].n = M - 1&amp;lt;/math&amp;gt;, call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, index &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;shiftRight = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.keys[1] = K&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p := p.children[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
&lt;br /&gt;
Basically, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the removal procedure are fulfilled after the preprocessing.&lt;br /&gt;
&lt;br /&gt;
If the tree is empty (Step 1), the proof is trivial, so consider the case that the tree is non-empty.&lt;br /&gt;
&lt;br /&gt;
Implementation invariants #1, #2, and #8 are trivially fulfilled. Implementation invariants #3, #5, #6, and #7 are guaranteed by Steps 3.1.3 and 4.1.3-5 and by the postconditions of the subroutines called in Step 4.2, respectively. Implementation invariant #4 is guaranteed by Step 3.1.2 and the postconditions of the subroutines called in Step 4, respectively.&lt;br /&gt;
&lt;br /&gt;
The loop invariants of the removal procedure are only affected if Step 4 is executed. Loop invariants #1, #2, and #3 are obvious, #4 does not apply, and #5 is guaranteed by the subroutines called in Step 4.&lt;br /&gt;
&lt;br /&gt;
Obviously, the case distinction in Step 4 covers all possible cases.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If a leaf is reached:&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in that leaf, remove it.&lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; has already been seen, overwrite the found occurrence of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; with its immediate predecessor (which is &amp;lt;math&amp;gt;p.keys[p.n]&amp;lt;/math&amp;gt;).&lt;br /&gt;
## Terminate the algorithm&lt;br /&gt;
# Otherwise:&lt;br /&gt;
## Let &amp;lt;math&amp;gt;k \in \{0,\dots,p.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.children[k]&amp;lt;/math&amp;gt; is the next node where to descend.&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[k].n = M - 1&amp;lt;/math&amp;gt;, rearrange the current node at its children appropriately.&lt;br /&gt;
## Check whether &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the current node.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to aleaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in that leaf:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt;j \in \{k + 1,\dots,p.n\}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Remove the key at position &amp;lt;math&amp;gt;p.n&amp;lt;/math&amp;gt; in the node pointed by &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;found&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p'.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p'.keys[k] = K&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p'.keys[k] := p.keys[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Remove the key at position &amp;lt;math&amp;gt;p.n&amp;lt;/math&amp;gt; in the node pointed by &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise terminate the algorithm and return '''''false'''''&lt;br /&gt;
# Otherwise (that is, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; does not point to a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K &amp;gt; p.keys[k]&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[k].n = M - 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
### If &amp;lt;math&amp;gt;k = p.n&amp;lt;/math&amp;gt; (that is, no sibling to the right):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[k-1].n = M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: merge two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Otherwise (that is, &amp;lt;math&amp;gt;p.children[k-1].n &amp;gt; M -1&amp;lt;/math&amp;gt;): call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;shiftRight = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise (that is, &amp;lt;math&amp;gt;k &amp;lt; p.n&amp;lt;/math&amp;gt;):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[k+1].n = M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: merge two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Otherwise (that is, &amp;lt;math&amp;gt;p.children[k+1].n &amp;gt; M = 1)&amp;lt;/math&amp;gt;: call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; index &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;shiftRight = false&amp;lt;/math&amp;gt;.&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points:&lt;br /&gt;
### Set &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K &amp;gt; p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p := p.children[k]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
Analogously to the induction basis, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the removal procedure are maintained by an iteration of the main loop.&lt;br /&gt;
&lt;br /&gt;
Again, implementation invariants #1 and #2 are trivially fulfilled. In case points to a leaf, implementation invariants #4, #7, and #8 are trivially maintained as well. In this case, Steps 1.1.3 and 1.2.3 guarantee #3, Step 1.1.2 guarantees #5, and Steps 1.1.2 and 4 guarantee #6. In case does not point to a leaf, implementation invariants #3-8 are guaranteed by the subroutines called in Step 2.&lt;br /&gt;
&lt;br /&gt;
Finally, consider the loop invariants of the removal procedure. #1 is trivial; #2 is guaranteed by Step 2.4; #3 and #4.1 by Step 2.3; #4.2 by Step 4, and #5 by the subroutines called in Step 2.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the facts that&lt;br /&gt;
# &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is assumed to be fixed, and&lt;br /&gt;
# the height of a B-tree with &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees]] page).&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;br /&gt;
In the above specification, each node with exactly &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys is modified when visited. This is done for precautionary reasons only. With a slight modification, this can be avoided: when the leaf is reached, go back along the traversed path and modify each nodes with &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys until the first node with more than &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys is visited. Evidently, this reduces the number of modifications. However, chances are high that these nodes have to be modified sooner or later, so the true benefit is not clear. The version of the removal procedure presented here has primarily been selected because its loop invariant is simpler and more intuitive.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
	<entry>
		<id>https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_remove&amp;diff=492</id>
		<title>B-tree: remove</title>
		<link rel="alternate" type="text/html" href="https://wiki.algo.informatik.tu-darmstadt.de/index.php?title=B-tree:_remove&amp;diff=492"/>
		<updated>2014-10-01T06:18:23Z</updated>

		<summary type="html">&lt;p&gt;Jhohmann: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Checkup]]&lt;br /&gt;
&lt;br /&gt;
[[Category:B-Tree]]&lt;br /&gt;
[[Category:Algorithm]]&lt;br /&gt;
== General Information ==&lt;br /&gt;
'''Algorithmic problem:''' [[Sorted sequence#Remove|Sorted sequence: remove]]&lt;br /&gt;
&lt;br /&gt;
'''Type of algorithm:''' loop&lt;br /&gt;
&lt;br /&gt;
'''Auxiliary data:'''&lt;br /&gt;
## Pointers, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p_2&amp;lt;/math&amp;gt; of type &amp;quot;pointer to B-tree node&amp;quot;.&lt;br /&gt;
## A Boolean variable '''''found''''', which is '''''false''''', in the beginning and set '''''true''''' once the key &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; to be removed is seen.&lt;br /&gt;
&lt;br /&gt;
== Abstract View ==&lt;br /&gt;
&lt;br /&gt;
'''Invariant:'''&lt;br /&gt;
# &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a node of the B-tree.&lt;br /&gt;
# If &amp;lt;math&amp;gt;found = false&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
# It is &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt; if, and only if, &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained at least once in one of the current nodes of previous iterations.&lt;br /&gt;
# If &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;&lt;br /&gt;
## &amp;lt;math&amp;gt;p'&amp;lt;/math&amp;gt; points to a node where &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is currently stored.&lt;br /&gt;
## The [[Directed Tree#Order of Tree Nodes|immediate predecessor]] of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the [[Directed Tree#Ranges of Search Tree Nodes|range]] of the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to the root, at least two keys are currently stored in the root; otherwise, at least &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; keys are currently stored in the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points.&lt;br /&gt;
&lt;br /&gt;
'''Variant:''' &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is redirected to a node one level deeper.&lt;br /&gt;
&lt;br /&gt;
'''Break condition:''' &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to a leaf.&lt;br /&gt;
&lt;br /&gt;
== Induction Basis ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If the tree is empty, terminate the algorithm and return '''''false'''''&lt;br /&gt;
# The pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; is initialized so as to point to the root &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;&lt;br /&gt;
# If &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is a leaf:&lt;br /&gt;
## Remove &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; if contained in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;.&lt;br /&gt;
## If &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is empty now, make the tree empty.&lt;br /&gt;
## Terminate the algorithm and return '''''true''''' if &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; was contained in &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, '''''false''''' otherwise.&lt;br /&gt;
# Otherwise, if &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; contains exactly one key and is not a leaf: rearrange the root and its two children appropriately.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# If the tree is empty, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# Let &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; point to the root.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, the root is a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in the root, say at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Remove the occurrence of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; at position &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
### If the root is empty now, make the tree an empty tree.&lt;br /&gt;
### Otherwise (that is, the root is still non-empty):&lt;br /&gt;
#### For &amp;lt;math&amp;gt;j \in \{k+1,\dots,p.n\}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise, terminate the algorithm and return '''''false'''''.&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.n = 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[0].n = p.children[1].n = M - 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.key[M] := p.key[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p_1 := p.children[0]&amp;lt;/math&amp;gt; and &amp;lt;/math&amp;gt;p_2 := p.children[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.children[0] := p_1.children[0]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p.children[M] := p_2.children[0]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt; j = 1,\dots,M-1&amp;lt;/math&amp;gt; set &amp;lt;math&amp;gt;p.keys[j] := p_1.keys[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p.children[j] := p_1.children[j]&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;p.keys[M + j] := p_2.keys[j]&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;p.children[M + j] := p_2.children[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := 2M - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Otherwise:&lt;br /&gt;
### If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;:&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[0].n = M - 1&amp;lt;/math&amp;gt;, call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, index &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;shiftRight = false&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.keys[1] = K&amp;lt;math&amp;gt;, set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;found := true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p := p.children[0]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise (that is, &amp;lt;math&amp;gt;K &amp;gt; p.key[1]&amp;lt;/math&amp;gt;):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[1].n = M - 1&amp;lt;/math&amp;gt;, call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;, index &amp;lt;math&amp;gt;1&amp;lt;/math&amp;gt;, and &amp;lt;math&amp;gt;shiftRight = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.keys[1] = K&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Set &amp;lt;math&amp;gt;p := p.children[1]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Proof: ===&lt;br /&gt;
&lt;br /&gt;
Basically, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the removal procedure are fulfilled after the preprocessing.&lt;br /&gt;
&lt;br /&gt;
If the tree is empty (Step 1), the proof is trivial, so consider the case that the tree is non-empty.&lt;br /&gt;
&lt;br /&gt;
Implementation invariants #1, #2, and #8 are trivially fulfilled. Implementation invariants #3, #5, #6, and #7 are guaranteed by Steps 3.1.3 and 4.1.3-5 and by the postconditions of the subroutines called in Step 4.2, respectively. Implementation invariant #4 is guaranteed by Step 3.1.2 and the postconditions of the subroutines called in Step 4, respectively.&lt;br /&gt;
&lt;br /&gt;
The loop invariants of the removal procedure are only affected if Step 4 is executed. Loop invariants #1, #2, and #3 are obvious, #4 does not apply, and #5 is guaranteed by the subroutines called in Step 4.&lt;br /&gt;
&lt;br /&gt;
Obviously, the case distinction in Step 4 covers all possible cases.&lt;br /&gt;
&lt;br /&gt;
== Induction Step ==&lt;br /&gt;
&lt;br /&gt;
=== Abstract view: ===&lt;br /&gt;
&lt;br /&gt;
# If a leaf is reached:&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in that leaf, remove it.&lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; has already been seen, overwrite the found occurrence of &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; with its immediate predecessor (which is &amp;lt;math&amp;gt;p.keys[p.n]&amp;lt;/math&amp;gt;).&lt;br /&gt;
## Terminate the algorithm&lt;br /&gt;
# Otherwise:&lt;br /&gt;
## Let &amp;lt;math&amp;gt;k \in \{0,\dots,p.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.children[k]&amp;lt;/math&amp;gt; is the next node where to descend.&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[k].n = M - 1&amp;lt;/math&amp;gt;, rearrange the current node at its children appropriately.&lt;br /&gt;
## Check whether &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is in the current node.&lt;br /&gt;
&lt;br /&gt;
=== Implementation: ===&lt;br /&gt;
&lt;br /&gt;
# If &amp;lt;math&amp;gt;p.children[0] = void&amp;lt;/math&amp;gt; (that is, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points to aleaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in that leaf:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### For &amp;lt;math&amp;gt;j \in \{k + 1,\dots,p.n\}&amp;lt;/math&amp;gt; (in this order), set &amp;lt;math&amp;gt;p.keys[j-1] := p.keys[j]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Remove the key at position &amp;lt;math&amp;gt;p.n&amp;lt;/math&amp;gt; in the node pointed by &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise, if &amp;lt;math&amp;gt;found&amp;lt;/math&amp;gt;:&lt;br /&gt;
### Let &amp;lt;math&amp;gt;k \in \{1,\dots,p'.n\}&amp;lt;/math&amp;gt; such that &amp;lt;math&amp;gt;p'.keys[k] = K&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p'.keys[k] := p.keys[p.n]&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Remove the key at position &amp;lt;math&amp;gt;p.n&amp;lt;/math&amp;gt; in the node pointed by &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt;&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p.n := p.n - 1&amp;lt;/math&amp;gt;&lt;br /&gt;
### Terminate the algorithm and return '''''true'''''&lt;br /&gt;
## Otherwise terminate the algorithm and return '''''false'''''&lt;br /&gt;
# Otherwise (that is, &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; does not point to a leaf):&lt;br /&gt;
## If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K &amp;gt; p.keys[k]&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;p.children[k].n = M - 1&amp;lt;/math&amp;gt;:&lt;br /&gt;
### If &amp;lt;math&amp;gt;k = p.n&amp;lt;/math&amp;gt; (that is, no sibling to the right):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[k-1].n = M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: merge two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Otherwise (that is, &amp;lt;math&amp;gt;p.children[k-1].n &amp;gt; M -1&amp;lt;/math&amp;gt;): call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; index &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;shiftRight = true&amp;lt;/math&amp;gt;.&lt;br /&gt;
### Otherwise (that is, &amp;lt;math&amp;gt;k &amp;lt; p.n&amp;lt;/math&amp;gt;):&lt;br /&gt;
#### If &amp;lt;math&amp;gt;p.children[k+1].n = M - 1&amp;lt;/math&amp;gt;: call [[B-Trees|B-tree: merge two siblings]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; and index &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt;.&lt;br /&gt;
#### Otherwise (that is, &amp;lt;math&amp;gt;p.children[k+1].n &amp;gt; M = 1)&amp;lt;/math&amp;gt;: call [[B-Tree:Shift_Key_to_Sibling]] with pointer &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; index &amp;lt;math&amp;gt;k + 1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;shiftRight = false&amp;lt;/math&amp;gt;.&lt;br /&gt;
## If &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; is contained in the node to which &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; points:&lt;br /&gt;
### Set &amp;lt;math&amp;gt;found = true&amp;lt;/math&amp;gt;&lt;br /&gt;
### Set &amp;lt;math&amp;gt;p' := p&amp;lt;/math&amp;gt;&lt;br /&gt;
## If &amp;lt;math&amp;gt;K \leq p.keys[1]&amp;lt;/math&amp;gt;, set &amp;lt;math&amp;gt;k := 0&amp;lt;/math&amp;gt;; otherwise, let &amp;lt;math&amp;gt;k \in \{1,\dots,p.n\}&amp;lt;/math&amp;gt; be maximal such that &amp;lt;math&amp;gt;K &amp;gt; p.keys[k]&amp;lt;/math&amp;gt;.&lt;br /&gt;
## Set &amp;lt;math&amp;gt;p := p.children[k]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Correctness: ===&lt;br /&gt;
&lt;br /&gt;
Analogously to the induction basis, we have to verify that the [[B-Trees|implementation invariants of the B-tree data structure]] and the above-mentioned loop invariants of the removal procedure are maintained by an iteration of the main loop.&lt;br /&gt;
&lt;br /&gt;
Again, implementation invariants #1 and #2 are trivially fulfilled. In case points to a leaf, implementation invariants #4, #7, and #8 are trivially maintained as well. In this case, Steps 1.1.3 and 1.2.3 guarantee #3, Step 1.1.2 guarantees #5, and Steps 1.1.2 and 4 guarantee #6. In case does not point to a leaf, implementation invariants #3-8 are guaranteed by the subroutines called in Step 2.&lt;br /&gt;
&lt;br /&gt;
Finally, consider the loop invariants of the removal procedure. #1 is trivial; #2 is guaranteed by Step 2.4; #3 and #4.1 by Step 2.3; #4.2 by Step 4, and #5 by the subroutines called in Step 2.&lt;br /&gt;
&lt;br /&gt;
== Complexity ==&lt;br /&gt;
&lt;br /&gt;
'''Statement:''' The asymptotic complexity is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; in the best and worst case.&lt;br /&gt;
&lt;br /&gt;
'''Proof:''' Follows immediately from the facts that&lt;br /&gt;
# &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is assumed to be fixed, and&lt;br /&gt;
# the height of a B-tree with &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; nodes is in &amp;lt;math&amp;gt;\Theta(\log n)&amp;lt;/math&amp;gt; (cf. the remark clause of the [[B-Trees]] page).&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;br /&gt;
In the above specification, each node with exactly &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys is modified when visited. This is done for precautionary reasons only. With a slight modification, this can be avoided: when the leaf is reached, go back along the traversed path and modify each nodes with &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys until the first node with more than &amp;lt;math&amp;gt;M - 1&amp;lt;/math&amp;gt; keys is visited. Evidently, this reduces the number of modifications. However, chances are high that these nodes have to be modified sooner or later, so the true benefit is not clear. The version of the removal procedure presented here has primarily been selected because its loop invariant is simpler and more intuitive.&lt;/div&gt;</summary>
		<author><name>Jhohmann</name></author>
	</entry>
</feed>