<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Divide and conquer algorithm &#8211; stoimen&#039;s web log</title>
	<atom:link href="/tag/divide-and-conquer-algorithm/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>on web development</description>
	<lastBuildDate>Tue, 13 Feb 2018 08:18:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.3</generator>
	<item>
		<title>Computer Algorithms: Strassen&#8217;s Matrix Multiplication</title>
		<link>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/</link>
		<comments>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 14:16:51 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Algebra]]></category>
		<category><![CDATA[Binary operations]]></category>
		<category><![CDATA[Coppersmith–Winograd algorithm]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[faster solution]]></category>
		<category><![CDATA[final solution]]></category>
		<category><![CDATA[given solution]]></category>
		<category><![CDATA[graph algorithms]]></category>
		<category><![CDATA[Linear algebra]]></category>
		<category><![CDATA[mathematician]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Matrix]]></category>
		<category><![CDATA[matrix multiplication algorithm]]></category>
		<category><![CDATA[Matrix theory]]></category>
		<category><![CDATA[Multiplication]]></category>
		<category><![CDATA[Multiplication algorithm]]></category>
		<category><![CDATA[n^3 algorithm]]></category>
		<category><![CDATA[n^3 matrix multiplication algorithm]]></category>
		<category><![CDATA[Numerical linear algebra]]></category>
		<category><![CDATA[NxN]]></category>
		<category><![CDATA[Operations research]]></category>
		<category><![CDATA[purpose algorithm]]></category>
		<category><![CDATA[sort algorithm]]></category>
		<category><![CDATA[sub-solutions]]></category>
		<category><![CDATA[Volker Strassen]]></category>

		<guid isPermaLink="false">/?p=3466</guid>
		<description><![CDATA[Introduction The Strassen’s method of matrix multiplication is a typical divide and conquer algorithm. We’ve seen so far some divide and conquer algorithms like merge sort and the Karatsuba’s fast multiplication of large numbers. However let’s get again on what’s behind the divide and conquer approach. Unlike the dynamic programming where we “expand” the solutions &#8230; <a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Strassen&#8217;s Matrix Multiplication</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" rel="bookmark" title="Computer Algorithms: Karatsuba Fast Multiplication">Computer Algorithms: Karatsuba Fast Multiplication </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>The Strassen’s method of matrix multiplication is a typical divide and conquer algorithm. We’ve seen so far some divide and conquer algorithms like <a href="/2012/03/05/computer-algorithms-merge-sort/" title="Computer Algorithms: Merge Sort">merge sort</a> and the <a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" title="Computer Algorithms: Karatsuba Fast Multiplication">Karatsuba’s fast multiplication</a> of large numbers. However let’s get again on what’s behind the divide and conquer approach.</p>
<p>Unlike the dynamic programming where we “expand” the solutions of sub-problems in order to get the final solution, here we are talking more on joining sub-solutions together. These solutions of some sub-problems of the general problem are equal and their merge is somehow well defined.</p>
<p>A typical example is the merge sort algorithm. In merge sort we have two sorted arrays and all we want is to get the array representing their union again sorted. Of course, the tricky part in merge sort is the merging itself. That’s because we’ve to pass through the two arrays, A and B, and we’ve to compare each “pair” of items representing an item from A and from B. A bit off topic, but this is the weak point of merge sort and although its worst-case time complexity is O(n.log(n)), quicksort is often preferred in practice because there’s no “merge”. <a href="/2012/03/13/computer-algorithms-quicksort/" title="Computer Algorithms: Quicksort">Quicksort</a> just concatenates the two sub-arrays. Note that in quicksort the sub-arrays aren’t with an equal length in general and although its worst-case time complexity is O(n^2) it often outperforms merge sort.</p>
<p>This simple example from the paragraph above shows us how sometimes merging the solutions of two sub-problems actually isn’t a trivial task to do. Thus we must be careful when applying any divide and conquer approach.</p>
<h2>History</h2>
<p><a href="http://en.wikipedia.org/wiki/Volker_Strassen" title="Volker Strassen" target="_blank">Volker Strassen</a> is a German mathematician born in 1936. He is well known for his works on probability, but in the computer science and algorithms he’s mostly recognized because of his algorithm for matrix multiplication that’s still one of the main methods that outperforms the general matrix multiplication algorithm.</p>
<p>Strassen firstly published this algorithm in 1969 and proved that the n^3 algorithm isn’t the optimal one. Actually the given solution by Strassen is slightly better, but his contribution is enormous because this resulted in many more researches about matrix multiplication that led to some faster approaches, i.e. <a href="http://en.wikipedia.org/wiki/Coppersmith%E2%80%93Winograd_algorithm" title="Coppersmith-Winograd algorithm" target="_blank">the Coppersmith-Winograd algorithm</a> with O(n^2,3737).<span id="more-3466"></span></p>
<h2>Overview</h2>
<p>The general algorithm on multiplying two matrices A[NxN] and B[NxN] is fairly simple. Although it’s more difficult than multiplying two numbers and also it is not commutative it’s still very simple – but slow.</p>
<p>Let’s first define what’s a matrix A[NxN]. As we speak about matrices NxN we usually think of a square grid with N rows and N columns. In each row and column A[i][j] we’ve a value. </p>
<figure id="attachment_3489" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/1.-Square-matrix.png"><img src="/wp-content/uploads/2012/11/1.-Square-matrix.png" alt="Square matrix" title="Square matrix" width="620" height="399" class="size-full wp-image-3489" srcset="/wp-content/uploads/2012/11/1.-Square-matrix.png 620w, /wp-content/uploads/2012/11/1.-Square-matrix-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Of course, as developers, we can think of a matrix as a two-dimensional array. </p>
<pre lang="PHP">
// PHP two-dimensional array
$a = array(
    0 => array($v1, $v2, $v3, $v4),
    1 => array($v5, $v6, $v7, $v8),
    2 => array($v9, $v10, $v11, $v12),
); 
</pre>
<p>Don’t forget that a NxN matrix is just a private case for a matrix. We can equally likely have any other size of a matrix NxM (N <> M). </p>
<p>However the size of a matrix is crucial in order to multiply it with another matrix. Why is that? </p>
<p>As I said above multiplying matrices isn’t the same as multiplying numbers. First of all this operation isn’t commutative.</p>
<figure id="attachment_3488" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/2.-Commutative-problem.png"><img src="/wp-content/uploads/2012/11/2.-Commutative-problem.png" alt="Commutative problem" title="Commutative problem" width="620" height="399" class="size-full wp-image-3488" srcset="/wp-content/uploads/2012/11/2.-Commutative-problem.png 620w, /wp-content/uploads/2012/11/2.-Commutative-problem-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>And the second problem is the way you multiply two matrices A with B.</p>
<figure id="attachment_3487" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png"><img src="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png" alt="Matrix Multiplication" title="Matrix Multiplication" width="620" height="399" class="size-full wp-image-3487" srcset="/wp-content/uploads/2012/11/3.-Matrix-Multiplication.png 620w, /wp-content/uploads/2012/11/3.-Matrix-Multiplication-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Just because this works with NxN matrices we can see the problem with multiplying rectangular matrices. Indeed, this wouldn’t be possible unless the second dimension of A isn’t exactly equal to the first dimension of B. </p>
<figure id="attachment_3486" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png"><img src="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png" alt="Rectangular Matrix Multiplication" title="Rectangular Matrix Multiplication" width="620" height="399" class="size-full wp-image-3486" srcset="/wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication.png 620w, /wp-content/uploads/2012/11/4.-Rect-Matrix-Multiplication-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Hopefully we are now talking about square matrices with exactly the same dimensions.</p>
<p>OK, so now we know how to multiply two square matrices (with the same dimensions NxN) and now let’s evaluate the time complexity for the general purpose algorithm.</p>
<p>As we know A.B = C only when:</p>
<pre>
C[i][j] = sum(A[i][k] * B[k][j]) for k = 0 .. n
</pre>
<p>Thus we have n^3 operations. Let’s try to find out a divide and conquer approach.</p>
<p>Indeed this isn’t difficult in case of matrices because as we know we can divide in matrix in smaller sub-matrices.</p>
<figure id="attachment_3485" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png"><img src="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png" alt="Divide and Conquer" title="Divide and Conquer" width="620" height="399" class="size-full wp-image-3485" srcset="/wp-content/uploads/2012/11/5.-Divide-and-Conquer.png 620w, /wp-content/uploads/2012/11/5.-Divide-and-Conquer-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Now what do we have?</p>
<figure id="attachment_3484" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png"><img src="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png" alt="Divide and Conquer Result" title="Divide and Conquer Result" width="620" height="399" class="size-full wp-image-3484" srcset="/wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result.png 620w, /wp-content/uploads/2012/11/6.-Divide-and-Conquer-Result-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<p>Again &#8211; the same complexity – we have 8 products and 4 sums. Where’s the catch? </p>
<p>Of course in order to get faster solution we’ve to be looking as Strassen did in 1969. He defined P1, P2, P3, P4, P5, P6 and P7 as defined on the image below.</p>
<figure id="attachment_3483" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png"><img src="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png" alt="Strassen&#039;s Algorithm" title="Strassen&#039;s Algorithm" width="620" height="399" class="size-full wp-image-3483" srcset="/wp-content/uploads/2012/11/7.-Strassens-Algorithm.png 620w, /wp-content/uploads/2012/11/7.-Strassens-Algorithm-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<h2>Complexity</h2>
<p>As I mentioned above the Strassen’s algorithm is slightly faster than the general matrix multiplication algorithm. The general algorithm’s time complexity is O(n^3), while the Strassen’s algorithm is O(n^2.80).</p>
<p>You can see on the chart below how slightly faster is this even for large n.</p>
<figure id="attachment_3482" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/11/Strassens-Complexity.png"><img src="/wp-content/uploads/2012/11/Strassens-Complexity.png" alt="Strassen&#039;s Complexity" title="Strassen&#039;s Complexity" width="600" height="371" class="size-full wp-image-3482" srcset="/wp-content/uploads/2012/11/Strassens-Complexity.png 600w, /wp-content/uploads/2012/11/Strassens-Complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">&nbsp;</figcaption></figure>
<h2>Application</h2>
<p>Although this algorithm seems to be more close to pure mathematics than to computer practically everywhere we use NxN arrays we can benefit from matrix multiplication.</p>
<p>In the other hand the algorithm of Strassen is not much faster than the general n^3 matrix multiplication algorithm. That’s very important because for small n (usually n < 45) the general algorithm is practically a better choice. However as you can see from the chart above for n > 100 the difference can be very big.</p>
<p>In the same time typically NxN arrays are used always when we talk about adjacency matrix of graphs |V| = n and some graph algorithms practically depend on matrix multiplication. </p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" rel="bookmark" title="Computer Algorithms: Karatsuba Fast Multiplication">Computer Algorithms: Karatsuba Fast Multiplication </a></li>
<li><a href="/2012/10/22/computer-algorithms-bellman-ford-shortest-path-in-a-graph/" rel="bookmark" title="Computer Algorithms: Bellman-Ford Shortest Path in a Graph">Computer Algorithms: Bellman-Ford Shortest Path in a Graph </a></li>
<li><a href="/2012/08/31/computer-algorithms-graphs-and-their-representation/" rel="bookmark" title="Computer Algorithms: Graphs and their Representation">Computer Algorithms: Graphs and their Representation </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/11/26/computer-algorithms-strassens-matrix-multiplication/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Karatsuba Fast Multiplication</title>
		<link>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/</link>
		<comments>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/#comments</comments>
		<pubDate>Tue, 15 May 2012 19:52:59 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Anatolii Alexeevitch Karatsuba]]></category>
		<category><![CDATA[Andrey Kolmogorov]]></category>
		<category><![CDATA[Cohen-Sutherland]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[Karatsuba algorithm]]></category>
		<category><![CDATA[Mathematics]]></category>
		<category><![CDATA[Multiplication]]></category>
		<category><![CDATA[Multiplication algorithm]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[structured algorithm]]></category>

		<guid isPermaLink="false">/?p=3121</guid>
		<description><![CDATA[Introduction Typically multiplying two n-digit numbers require n2 multiplications. That is actually how we, humans, multiply numbers. Let’s take a look of an example in case we’ve to multiply two 2-digit numbers. 12 x 15 = ? OK, we know that the answer is 180 and there are lots of intuitive methods that help us &#8230; <a href="/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Karatsuba Fast Multiplication</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" rel="bookmark" title="Computer Algorithms: Strassen&#8217;s Matrix Multiplication">Computer Algorithms: Strassen&#8217;s Matrix Multiplication </a></li>
<li><a href="/2012/05/08/computer-algorithms-determine-if-a-number-is-prime/" rel="bookmark" title="Computer Algorithms: Determine if a Number is Prime">Computer Algorithms: Determine if a Number is Prime </a></li>
<li><a href="/2012/12/24/computer-algorithms-sorting-in-linear-time/" rel="bookmark" title="Computer Algorithms: Sorting in Linear Time">Computer Algorithms: Sorting in Linear Time </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Typically multiplying two n-digit numbers require n<sup>2</sup> multiplications. That is actually how we, humans, multiply numbers. Let’s take a look of an example in case we’ve to multiply two 2-digit numbers.</p>
<pre lang="php">12 x 15 = ?</pre>
<p>OK, we know that the answer is 180 and there are lots of intuitive methods that help us get the right answer. Indeed 12 x 15 it’s just a bit more difficult to calculate than 10 x 15, because multiplying by 10 it really easy &#8211; we just add one 0 at the end of the number. Thus 15 x 10 equals 150. But now again on 12 x 15 &#8211; we know that this equals 10 x 15 (which is 150) and 2 x 15, which is also very easy to calculate and it is 30. The result of 12&#215;15 will be 150 + 30, which fortunately isn’t difficult to get and equals to 180.</p>
<p>That was easy but in some cases the calculations are a bit more difficult and we need a structured algorithm to get the right answer. What about 65 x 97? That is not so easy as 12 x 15, right?</p>
<p>The algorithm we know from the primary school, described on the diagram below, is well structured and help us multiply two numbers.</p>
<div class="mceTemp">
<dl id="attachment_3139" class="wp-caption alignnone" style="width: 494px;">
<dt class="wp-caption-dt"><a href="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png"><img class="size-full wp-image-3139" title="Typical Multiplication" src="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png" alt="Typical Multiplication" width="484" height="518" srcset="/wp-content/uploads/2012/05/1.-Typical-Multiplication.png 484w, /wp-content/uploads/2012/05/1.-Typical-Multiplication-280x300.png 280w" sizes="(max-width: 484px) 100vw, 484px" /></a></dt>
<dd class="wp-caption-dd"></dd>
</dl>
</div>
<p>We see that even for two-digit numbers this is quite difficult &#8211; we have 4 multiplications and some additions.<span id="more-3121"></span></p>
<figure id="attachment_3143" style="width: 484px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png"><img src="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png" alt="Number of Multiplications" title="Number of Multiplications" width="484" height="518" class="size-full wp-image-3143" srcset="/wp-content/uploads/2012/05/2.-Number-of-Multiplications.png 484w, /wp-content/uploads/2012/05/2.-Number-of-Multiplications-280x300.png 280w" sizes="(max-width: 484px) 100vw, 484px" /></a><figcaption class="wp-caption-text">We need 4 multiplications in order to calculate the product of two 2-digit numbers!</figcaption></figure>
<p>However so far we know how to multiply numbers, the only problem is that our task becomes very difficult as the numbers grow. If multiplying 65 by 97 was somehow easy, what about</p>
<pre lang="php">374773294776321
x
222384759707982</pre>
<p>It seems almost impossible.</p>
<h3>History</h3>
<p><a title="Andrey Kolmogorov" href="http://en.wikipedia.org/wiki/Andrey_Kolmogorov" target="_blank">Andrey Kolmogorov</a> is one of the brightest russian mathematicians of the 20th century. In 1960, during a seminar, Kolmogorov stated that two n-digit numbers can’t be multiplied with less than n<sup>2</sup> multiplications!<br />
Only a week later a 23-year young student called <a title="Anatolii Alexeevitch Karatsuba" href="http://en.wikipedia.org/wiki/Anatolii_Alexeevitch_Karatsuba" target="_blank">Anatolii Alexeevitch Karatsuba</a> proved that the multiplication of two n-digit numbers can be computed with n ^ lg(3) multiplications with an ingenious divide and conquer approach.</p>
<h2>Overview</h2>
<p>Basically Karatsuba stated that if we have to multiply two n-digit numbers x and y, this can be done with the following operations, assuming that B is the base of and m &lt; n.</p>
<p>First both numbers x and y can be represented as x1,x2 and y1,y2 with the following formula.</p>
<pre lang="PHP">
x = x1 * B^m + x2 
y = y1 * B^m + y2 
</pre>
<p>Obviously now xy will become as the following product.</p>
<pre lang="PHP">
xy = (x1 * B^m + x2)(y1 * B^m + y2) =>

a = x1 * y1
b = x1 * y2 + x2 * y1
c = x2 * y2
</pre>
<p>Finally xy will become:</p>
<pre lang="PHP">
xy = a * B^2m + b * B^m + c
</pre>
<p>However a, b and c can be computed at least with four multiplication, which isn’t a big optimization. That is why Karatsuba came up with the brilliant idea to calculate b with the following formula:</p>
<pre lang="PHP">
b = (x1 + x2)(y1 + y2) - a - c
</pre>
<p>That make use of only three multiplications to get xy.</p>
<p>Let’s see this formula by example. </p>
<pre lang="PHP">
47 x 78

x = 47
x = 4 * 10 + 7

x1 = 4
x2 = 7

y = 78
y = 7 * 10 + 8

y1 = 7
y2 = 8

a = x1 * y1 = 4 * 7 = 28
c = x2 * y2 = 7 * 8 = 56
b = (x1 + x2)(y1 + y2) - a - c = 11 * 15 - 28 - 56
</pre>
<p>Now the thing is that 11 * 15 it’s again a multiplication between 2-digit numbers, but fortunately we can apply the same rules two them. This makes the algorithm of Karatsuba a perfect example of the “divide and conquer” algorithm.</p>
<h2>Implementation</h2>
<h3>Standard Multiplication</h3>
<p>Typically the standard implementation of multiplication of n-digit numbers require n<sup>2</sup> multiplications as you can see from the following <a href="/category/php/" title="PHP on stoimen.com">PHP</a> implementation.</p>
<pre lang="PHP">
$x = array(1,2,3,4);
$y = array(5,6,7,8);

function multiply($x, $y)
{	
	$len_x = count($x);
	$len_y = count($y);
	$half_x = ceil($len_x / 2);
	$half_y = ceil($len_y / 2);
	$base = 10;

	// bottom of the recursion
	if ($len_x == 1 && $len_y == 1) {
		return $x[0] * $y[0];
	}
	
	$x_chunks = array_chunk($x, $half_x);
	$y_chunks = array_chunk($y, $half_y);
	
	// predefine aliases
	$x1 = $x_chunks[0];
	$x2 = $x_chunks[1];
	$y1 = $y_chunks[0];
	$y2 = $y_chunks[1];
	
	return  multiply($x1, $y1) * pow($base, $half_x * 2) 					// a
		 	+ (multiply($x1, $y2) + multiply($x2, $y1)) * pow($base, $half_x) 	// b
		 	+ multiply($x2, $y2);							// c
}

// 7 006 652
echo multiply($x, $y);
</pre>
<h3>Karatsuba Multiplication</h3>
<p>Karatsuba replaces two of the multiplications &#8211; this of x1 * y2 + x2 * y1 with only one &#8211; (x1 + x2)(y1 + y2) and this makes the algorithm faster.</p>
<pre lang="PHP">
$x = array(1,2,3,4);
$y = array(5,6,7,8);

function karatsuba($x, $y) 
{
	$len_x = count($x);
	$len_y = count($y);
	
	// bottom of the recursion
	if ($len_x == 1 && $len_y == 1) {
		return $x[0] * $y[0];
	} 
	if ($len_x == 1 || $len_y == 1) {
		$t1 = implode('', $x);
		$t2 = implode('', $y);
		return (int)$t1 * $t2;
	}
	
	$a = array_chunk($x, ceil($len_x/2));
	$b = array_chunk($y, ceil($len_y/2));
	
	$deg = floor($len_x/2);
	
	$x1 = $a[0];	// 1
	$x2 = $a[1];	// 2
	$y1 = $b[0];	// 1
	$y2 = $b[1];	// 2

	return  ($a = karatsuba($x1, $y1)) * pow(10, 2 * $deg)
			+ ($c = karatsuba($x2, $y2))
			+ (karatsuba(sum($x1, $x2), sum($y1, $y2)) - $a - $c) * pow(10, $deg);
}

// 7 006 652
echo karatsuba($x, $y);
</pre>
<h2>Complexity</h2>
<p>Assuming that we replace two of the multiplications with only one makes the program faster. The question is how fast. Karatsuba improves the multiplication process by replacing the initial complexity of O(n<sup>2</sup>) by O(n<sup>lg3</sup>), which as you can see on the diagram below is much faster for big n.</p>
<figure id="attachment_3141" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Karatsuba-Complexity.png"><img src="/wp-content/uploads/2012/05/Karatsuba-Complexity.png" alt="Karatsuba Complexity" title="Karatsuba Complexity" width="600" height="371" class="size-full wp-image-3141" srcset="/wp-content/uploads/2012/05/Karatsuba-Complexity.png 600w, /wp-content/uploads/2012/05/Karatsuba-Complexity-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">O(n^2) grows much faster than O(n^lg3)</figcaption></figure>
<h2>Application</h2>
<p>It&#8217;s obvious where the Karatsuba algorithm can be used. It is very efficient when it comes to integer multiplication, but that isn’t its only advantage. It is often used for polynomial multiplications.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2013/01/14/computer-algorithms-multiplication/" rel="bookmark" title="Computer Algorithms: Multiplication">Computer Algorithms: Multiplication </a></li>
<li><a href="/2012/11/26/computer-algorithms-strassens-matrix-multiplication/" rel="bookmark" title="Computer Algorithms: Strassen&#8217;s Matrix Multiplication">Computer Algorithms: Strassen&#8217;s Matrix Multiplication </a></li>
<li><a href="/2012/05/08/computer-algorithms-determine-if-a-number-is-prime/" rel="bookmark" title="Computer Algorithms: Determine if a Number is Prime">Computer Algorithms: Determine if a Number is Prime </a></li>
<li><a href="/2012/12/24/computer-algorithms-sorting-in-linear-time/" rel="bookmark" title="Computer Algorithms: Sorting in Linear Time">Computer Algorithms: Sorting in Linear Time </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/05/15/computer-algorithms-karatsuba-fast-multiplication/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>You think you know algorithms. Quiz results!</title>
		<link>/2012/05/09/you-think-you-know-algorithms-quiz-results-2/</link>
		<comments>/2012/05/09/you-think-you-know-algorithms-quiz-results-2/#respond</comments>
		<pubDate>Wed, 09 May 2012 14:14:50 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[quiz]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Bubble sort]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[Merge sort]]></category>
		<category><![CDATA[Quicksort]]></category>
		<category><![CDATA[Radix sort]]></category>
		<category><![CDATA[Sort]]></category>
		<category><![CDATA[Sorting algorithms]]></category>

		<guid isPermaLink="false">/?p=3115</guid>
		<description><![CDATA[Finally the results from &#8220;You think you know algorithms&#8221; are out. This time only 3 of you have answered correctly to all the questions. 1. Which string searching algorithm is faster? Morris-Pratt correct answer (ref) Brute force Rabin-Karp 2. Can you use radix sort for sorting floats? Yes No correct answer (ref) 3. Quicksort needs &#8230; <a href="/2012/05/09/you-think-you-know-algorithms-quiz-results-2/" class="more-link">Continue reading <span class="screen-reader-text">You think you know algorithms. Quiz results!</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/02/29/you-think-you-know-algorithms-quiz-results/" rel="bookmark" title="You think you know algorithms. Quiz results!">You think you know algorithms. Quiz results! </a></li>
<li><a href="/2012/03/16/you-think-you-know-php-quiz-results/" rel="bookmark" title="You think you know PHP. Quiz Results!">You think you know PHP. Quiz Results! </a></li>
<li><a href="/2012/03/07/you-think-you-know-javascript-quiz-results/" rel="bookmark" title="You think you know javascript. Quiz results!">You think you know javascript. Quiz results! </a></li>
<li><a href="/2012/03/13/computer-algorithms-quicksort/" rel="bookmark" title="Computer Algorithms: Quicksort">Computer Algorithms: Quicksort </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<p>Finally the results from <a href="/2012/04/11/you-think-you-know-algorithms/" title="You think you know algorithms" target="_blank">&#8220;You think you know algorithms&#8221;</a> are out. This time only <strong>3</strong> of you have answered correctly to all the questions.</p>
<h3>1. Which string searching algorithm is faster?</h3>
<ul>
<li>Morris-Pratt <span style="color: #339966;">correct answer</span> (<a href="/2012/04/09/computer-algorithms-morris-pratt-string-searching/" title="Computer Algorithms: Morris-Pratt String Searching" target="_blank">ref</a>)</li>
<li>Brute force</li>
<li>Rabin-Karp</li>
</ul>
<p><figure id="attachment_3123" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Answers1.png"><img src="/wp-content/uploads/2012/05/Answers1.png" alt="Quiz results for &quot;Which string searching algorithm is faster?&quot;" title="Quiz results for &quot;Which string searching algorithm is faster?&quot;" width="600" height="371" class="size-full wp-image-3123" srcset="/wp-content/uploads/2012/05/Answers1.png 600w, /wp-content/uploads/2012/05/Answers1-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text">  </figcaption></figure><br />
<span id="more-3115"></span></p>
<h3>2. Can you use radix sort for sorting floats?</h3>
<ul>
<li>Yes</li>
<li>No <span style="color: #339966;">correct answer</span> (<a href="/2012/03/19/computer-algorithms-radix-sort/" title="Computer Algorithms: Radix Sort" target="_blank">ref</a>)</li>
</ul>
<figure id="attachment_3124" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Answers2.png"><img src="/wp-content/uploads/2012/05/Answers2.png" alt="Quiz results for &quot;Can you use radix sort for sorting floats?&quot;" title="Quiz results for &quot;Can you use radix sort for sorting floats?&quot;" width="600" height="371" class="size-full wp-image-3124" srcset="/wp-content/uploads/2012/05/Answers2.png 600w, /wp-content/uploads/2012/05/Answers2-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h3>3. Quicksort needs additional memory space?</h3>
<ul>
<li>Yes</li>
<li>No</li>
<li>Only in iterative implementation <span style="color: #339966;">correct answer</span> (<a href="/2012/03/13/computer-algorithms-quicksort/" title="Computer Algorithms: Quicksort" target="_blank">ref</a>)</li>
<li>Only in recursive implementation</li>
</ul>
<figure id="attachment_3125" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Answers3.png"><img src="/wp-content/uploads/2012/05/Answers3.png" alt="Quiz results for &quot;Quicksort needs additional memory space?&quot;" title="Quiz results for &quot;Quicksort needs additional memory space?&quot;" width="600" height="371" class="size-full wp-image-3125" srcset="/wp-content/uploads/2012/05/Answers3.png 600w, /wp-content/uploads/2012/05/Answers3-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h3>4. In the worst case scenario which is slower?</h3>
<ul>
<li>Quicksort</li>
<li>Bubble sort</li>
<li>They are equally slow <span style="color: #339966;">correct answer</span> (<a href="/2012/03/13/computer-algorithms-quicksort/" title="Computer Algorithms: Quicksort" target="_blank">ref</a>)</li>
</ul>
<figure id="attachment_3126" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Answers4.png"><img src="/wp-content/uploads/2012/05/Answers4.png" alt="Quiz results for &quot;In the worst case scenario which is slower?&quot;" title="Quiz results for &quot;In the worst case scenario which is slower?&quot;" width="600" height="371" class="size-full wp-image-3126" srcset="/wp-content/uploads/2012/05/Answers4.png 600w, /wp-content/uploads/2012/05/Answers4-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h3>5. Is merge sort faster than quicksort in general?</h3>
<ul>
<li>Yes, its complexity is O(n.log(n)) always!</li>
<li>No, in practice quicksort is often faster than merge sort <span style="color: #339966;">correct answer</span> (ref)<a href="/2012/03/13/computer-algorithms-quicksort/" title="Computer Algorithms: Quicksort" target="_blank"></a></li>
</ul>
<figure id="attachment_3127" style="width: 600px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/05/Answers5.png"><img src="/wp-content/uploads/2012/05/Answers5.png" alt="Quiz results for &quot;Is merge sort faster than quicksort in general?&quot;" title="Quiz results for &quot;Is merge sort faster than quicksort in general?&quot;" width="600" height="371" class="size-full wp-image-3127" srcset="/wp-content/uploads/2012/05/Answers5.png 600w, /wp-content/uploads/2012/05/Answers5-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/02/29/you-think-you-know-algorithms-quiz-results/" rel="bookmark" title="You think you know algorithms. Quiz results!">You think you know algorithms. Quiz results! </a></li>
<li><a href="/2012/03/16/you-think-you-know-php-quiz-results/" rel="bookmark" title="You think you know PHP. Quiz Results!">You think you know PHP. Quiz Results! </a></li>
<li><a href="/2012/03/07/you-think-you-know-javascript-quiz-results/" rel="bookmark" title="You think you know javascript. Quiz results!">You think you know javascript. Quiz results! </a></li>
<li><a href="/2012/03/13/computer-algorithms-quicksort/" rel="bookmark" title="Computer Algorithms: Quicksort">Computer Algorithms: Quicksort </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/05/09/you-think-you-know-algorithms-quiz-results-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Quicksort</title>
		<link>/2012/03/13/computer-algorithms-quicksort/</link>
		<comments>/2012/03/13/computer-algorithms-quicksort/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 21:36:09 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[brilliant sorting algorithm]]></category>
		<category><![CDATA[Bubble sort]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[elegant general purpose sorting algorithm]]></category>
		<category><![CDATA[elegant solution]]></category>
		<category><![CDATA[faster algorithms]]></category>
		<category><![CDATA[Insertion sort]]></category>
		<category><![CDATA[Merge sort]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[purpose sorting algorithm]]></category>
		<category><![CDATA[Quicksort]]></category>
		<category><![CDATA[Recursion]]></category>
		<category><![CDATA[recursive solution]]></category>
		<category><![CDATA[Selection algorithm]]></category>
		<category><![CDATA[Sort]]></category>
		<category><![CDATA[Sorting algorithms]]></category>
		<category><![CDATA[Spreadsort]]></category>

		<guid isPermaLink="false">/?p=2899</guid>
		<description><![CDATA[Introduction When it comes to sorting items by comparing them merge sort is one very natural approach. It is natural, because simply divides the list into two equal sub-lists then sort these two partitions applying the same rule. That is a typical divide and conquer algorithm and it just follows the intuitive approach of speeding &#8230; <a href="/2012/03/13/computer-algorithms-quicksort/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Quicksort</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2010/06/18/friday-algorithms-iterative-quicksort/" rel="bookmark" title="Friday Algorithms: Iterative Quicksort">Friday Algorithms: Iterative Quicksort </a></li>
<li><a href="/2010/06/11/friday-algorithms-quicksort-difference-between-php-and-javascript/" rel="bookmark" title="Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript">Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript </a></li>
<li><a href="/2010/06/25/friday-algorithms-sorting-a-set-of-integers-far-quicker-than-quicksort/" rel="bookmark" title="Friday Algorithms: Sorting a Set of Integers &#8211; Far Quicker than Quicksort!">Friday Algorithms: Sorting a Set of Integers &#8211; Far Quicker than Quicksort! </a></li>
<li><a href="/2012/03/05/computer-algorithms-merge-sort/" rel="bookmark" title="Computer Algorithms: Merge Sort">Computer Algorithms: Merge Sort </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>When it comes to sorting items by comparing them <a href="/2012/03/05/computer-algorithms-merge-sort/" title="Computer Algorithms: Merge Sort">merge sort</a> is one very natural approach. It is natural, because simply divides the list into two equal sub-lists then sort these two partitions applying the same rule. That is a typical divide and conquer algorithm and it just follows the intuitive approach of speeding up the sorting process by reducing the number of comparisons. However there are other “divide and conquer” sorting algorithms that do not follow the merge sort scheme, while they have practically the same success. Such an algorithm is quicksort.</p>
<h2>Overview</h2>
<p>Back in 1960 <a href="http://en.wikipedia.org/wiki/Tony_Hoare" title="C. A. R. Hoare" target="_blank">C. A. R. Hoare</a> comes with a brilliant sorting algorithm. In general quicksort consists of some very simple steps. First we’ve to choose an element from the list (called a pivot) then we must put all the elements with value less than the pivot on the left side of the pivot and all the items with value greater than the pivot on its right side. After that we must repeat these steps for the left and the right sub-lists. That is quicksort! Simple and elegant! </p>
<p><figure id="attachment_2908" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/Quicksort.png"><img src="/wp-content/uploads/2012/03/Quicksort.png" alt="Quicksort" title="Quicksort" width="620" height="399" class="size-full wp-image-2908" srcset="/wp-content/uploads/2012/03/Quicksort.png 620w, /wp-content/uploads/2012/03/Quicksort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a><figcaption class="wp-caption-text"> </figcaption></figure><span id="more-2899"></span></p>
<p>It is a pure divide and conquer approach as merge sort, but while merge sort’s tricky part was merging the sorted sub-lists, in quicksort there are other things to consider. </p>
<p>First of all obviously the choice of a pivot is the bottleneck. Indeed it all depends on that pivot. Imagine that you choose the greatest value from the list &#8211; than you’ve to put all the other items of the list into the “left” sub-list. If you do that on each step you’ll practically go into the worst scenario and that is no good. The thing is that in the worst case quicksort is not so effective and it’s practically as slow as bubble sort and insertion sort. The good thing is that in practice with randomly generated lists there is not a high possibility to go into the worst case of quicksort.</p>
<h3>Choosing a pivot</h3>
<p>Of course the best pivot is the middle element from the list. Thus the list will be divided into two fairly equal sub-lists. The problem is that there’s not an easy way to get the middle element from a list and this will slow down the algorithm. So typically we can get for a pivot the first or the last item of the list.</p>
<p>After choosing a pivot the rest is simple. Put every item with a greater value on the right and every item with a lesser value on the left. Then we must sort the left and right sub-lists just as we did with the initial list. </p>
<p><a href="/wp-content/uploads/2012/03/MerginginQuicksort.png"><img src="/wp-content/uploads/2012/03/MerginginQuicksort.png" alt="Merging in Quicksort" title="Merging in Quicksort" width="620" height="399" class="alignnone size-full wp-image-2910" srcset="/wp-content/uploads/2012/03/MerginginQuicksort.png 620w, /wp-content/uploads/2012/03/MerginginQuicksort-300x193.png 300w" sizes="(max-width: 620px) 100vw, 620px" /></a></p>
<p>It’s clear that with this algorithm naturally we’re going into a recursive solution. Typically every divide and conquer approach is easy to implement with recursion. But because recursion can be heavy, there is an iterative approach.</p>
<h2>Implementation</h2>
<p>As I said above recursive approach is something very natural for quicksort as it follows the divide and conquer principles. On each step we divide the list in two and we pass those sub-lists to our recursive function. But recursion is dangerous sometimes, so an iterative approach is also available. Typically iterative approaches “model” recursion with extra memory and a model of a stack, which is our case. Here we have two examples of quicksort &#8211; recursive and iterative in PHP. Let’s go first with the recursion.</p>
<h3>Recursive Quicksort</h3>
<pre lang="PHP">
$list = array(5,3,9,8,7,2,4,1,6,5);
 
// recursive
function quicksort($array)
{
	if (count($array) == 0) {
    	return array();
	}
 
	$pivot = $array[0];
	$left = $right = array();
 
	for ($i = 1; $i < count($array); $i++) {
		if ($array[$i] < $pivot) {
			$left[] = $array[$i];
		} else {
			$right[] = $array[$i];
		}
	}
	
	return array_merge(quicksort($left), array($pivot), quicksort($right));
}

// 1, 2, 3, 4, 5, 5, 6, 7, 8, 9
print_r(quicksort($list));
</pre>
<h3>Iterative Quicksort</h3>
<pre lang="PHP">
$list = array(5,3,9,8,7,2,4,1,6,5);

// iterative
function quicksort_iterative($array)
{
    $stack = array($array);
    $sorted = array();
 
    while (count($stack) > 0) {
 
        $temp = array_pop($stack);
 
        if (count($temp) == 1) {
            $sorted[] = $temp[0];
            continue;
        }
 
        $pivot = $temp[0];
        $left = $right = array();
 
        for ($i = 1; $i < count($temp); $i++) {
            if ($pivot > $temp[$i]) {
                $left[] = $temp[$i];
            } else {
                $right[] = $temp[$i];
            }
        }
 
        $left[] = $pivot;
 
        if (count($right))
            array_push($stack, $right);
        if (count($left))
            array_push($stack, $left);
    }
 
    return $sorted;
}

// 1, 2, 3, 4, 5, 5, 6, 7, 8, 9
print_r(quicksort_iterative($list));
</pre>
<h2>Complexity</h2>
<p>The complexity of quicksort in the average case is O(n*log(n)) - same as Merge sort. The problem is that in the worst case it is O(n<sup>2</sup>) - same as bubble sort. Obviously the worst case is when we have an already sorted list, and we constantly take for a pivot the last element of the list. But we should consider that in practice we don’t quite use sorted lists that we have to sort again, right?</p>
<p><a href="/wp-content/uploads/2012/03/Quicksort.Average.Worst_.png"><img src="/wp-content/uploads/2012/03/Quicksort.Average.Worst_.png" alt="Quicksort average and worst case scenarios" title="Quicksort.Average.Worst" width="600" height="371" class="alignnone size-full wp-image-2909" srcset="/wp-content/uploads/2012/03/Quicksort.Average.Worst_.png 600w, /wp-content/uploads/2012/03/Quicksort.Average.Worst_-300x185.png 300w" sizes="(max-width: 600px) 100vw, 600px" /></a></p>
<h2>Application</h2>
<p>Quicksort is a great sorting algorithm and developers often go for it, but let's see some pros and cons of it.</p>
<h3>Why using quicksort</h3>
<ol>
<li>Recursive implementation is easy</li>
<li>In general its speed is same as merge sort - O(n*log(n))</li>
<li>Elegant solution with no tricky merging as merge sort</li>
</ol>
<h3>Why not using quicksort</h3>
<ol>
<li>As slow as bubble sort in the worst case!</li>
<li>Iterative implementation isn't easy</li>
<li>There are faster algorithms for some sets of data types</li>
</ol>
<p>Quicksort is beautiful because of the elegant idea behind its principles. Indeed if you have two sorted lists one with items with a greater value from a given value and the other with items smaller form that given value you can simply concatenate them and you can be sure that the resulting list will be sorted with no need of special merge. </p>
<p>In fact quicksort is a very elegant general purpose sorting algorithm and every developer should be familiar with its principles.</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2010/06/18/friday-algorithms-iterative-quicksort/" rel="bookmark" title="Friday Algorithms: Iterative Quicksort">Friday Algorithms: Iterative Quicksort </a></li>
<li><a href="/2010/06/11/friday-algorithms-quicksort-difference-between-php-and-javascript/" rel="bookmark" title="Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript">Friday Algorithms: Quicksort &#8211; Difference Between PHP and JavaScript </a></li>
<li><a href="/2010/06/25/friday-algorithms-sorting-a-set-of-integers-far-quicker-than-quicksort/" rel="bookmark" title="Friday Algorithms: Sorting a Set of Integers &#8211; Far Quicker than Quicksort!">Friday Algorithms: Sorting a Set of Integers &#8211; Far Quicker than Quicksort! </a></li>
<li><a href="/2012/03/05/computer-algorithms-merge-sort/" rel="bookmark" title="Computer Algorithms: Merge Sort">Computer Algorithms: Merge Sort </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/03/13/computer-algorithms-quicksort/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Computer Algorithms: Merge Sort</title>
		<link>/2012/03/05/computer-algorithms-merge-sort/</link>
		<comments>/2012/03/05/computer-algorithms-merge-sort/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 20:50:55 +0000</pubDate>
		<dc:creator><![CDATA[Stoimen]]></dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[Adaptive sort]]></category>
		<category><![CDATA[Best worst and average case]]></category>
		<category><![CDATA[Bubble sort]]></category>
		<category><![CDATA[comparison model sorting algorithm]]></category>
		<category><![CDATA[Divide and conquer algorithm]]></category>
		<category><![CDATA[Insertion sort]]></category>
		<category><![CDATA[interative solution]]></category>
		<category><![CDATA[interative solutions]]></category>
		<category><![CDATA[Merge sort]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Quicksort]]></category>
		<category><![CDATA[recursive solution]]></category>
		<category><![CDATA[Shell sort]]></category>
		<category><![CDATA[Sorting algorithms]]></category>
		<category><![CDATA[Strand sort]]></category>
		<category><![CDATA[three algorithms]]></category>
		<category><![CDATA[USD]]></category>

		<guid isPermaLink="false">/?p=2847</guid>
		<description><![CDATA[Introduction Basically sorting algorithms can be divided into two main groups. Such based on comparisons and such that are not. I already posted about some of the algorithms of the first group. Insertion sort, bubble sort and Shell sort are based on the comparison model. The problem with these three algorithms is that their complexity &#8230; <a href="/2012/03/05/computer-algorithms-merge-sort/" class="more-link">Continue reading <span class="screen-reader-text">Computer Algorithms: Merge Sort</span> <span class="meta-nav">&#8594;</span></a><div class='yarpp-related-rss'>

Related posts:<ol>
<li><a href="/2012/03/13/computer-algorithms-quicksort/" rel="bookmark" title="Computer Algorithms: Quicksort">Computer Algorithms: Quicksort </a></li>
<li><a href="/2010/07/02/friday-algorithms-javascript-merge-sort/" rel="bookmark" title="Friday Algorithms: JavaScript Merge Sort">Friday Algorithms: JavaScript Merge Sort </a></li>
<li><a href="/2012/02/27/computer-algorithms-shell-sort/" rel="bookmark" title="Computer Algorithms: Shell Sort">Computer Algorithms: Shell Sort </a></li>
<li><a href="/2012/03/19/computer-algorithms-radix-sort/" rel="bookmark" title="Computer Algorithms: Radix Sort">Computer Algorithms: Radix Sort </a></li>
</ol>
</div>
]]></description>
				<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Basically sorting algorithms can be divided into two main groups. Such based on comparisons and such that are not. I already posted about some of the algorithms of the first group. Insertion sort, bubble sort and Shell sort are based on the comparison model. The problem with these three algorithms is that their complexity is O(n<sup>2</sup>) so they are very slow. </p>
<p>So is it possible to sort a list of items by comparing their items faster than O(n<sup>2</sup>)? The answer is yes and here’s how we can do it.</p>
<p>The nature of those three algorithms mentioned above is that we almost compared each two items from initial list.</p>
<figure id="attachment_2860" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/Principlesofprimitivesortingalgorithms.png"><img src="/wp-content/uploads/2012/03/Principlesofprimitivesortingalgorithms.png" alt="Insertion sort and bubble sort make too many comparisons, exactly what merge sort tries to overcome!" title="Principles of primitive sorting algorithms" width="620" class="size-full wp-image-2860" srcset="/wp-content/uploads/2012/03/Principlesofprimitivesortingalgorithms.png 640w, /wp-content/uploads/2012/03/Principlesofprimitivesortingalgorithms-300x89.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption class="wp-caption-text">Insertion sort and bubble sort make too many comparisons, exactly what merge sort tries to overcome!</figcaption></figure>
<p>This, of course, is not the best approach and we don’t need to do that. Instead we can try to divide the list into smaller lists and then sort them. After sorting the smaller lists, which is supposed to be easier than sorting the entire initial list, we can try to merge the result into one sorted list. This technique is typically known as “divide and conquer”.</p>
<p>Normally if a problem is too difficult to solve, we can try to break it apart into smaller sub-sets of this problem and try to solve them. Then somehow we can merge the results of the solved problems. </p>
<p><figure id="attachment_2856" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/Divideandconquer.png"><img src="/wp-content/uploads/2012/03/Divideandconquer.png" alt="If it&#039;s too difficult to sort a large list of items, we can break it apart into smaller sub-lists and try to sort them!" title="Divide and conquer" width="620" class="size-full wp-image-2856" srcset="/wp-content/uploads/2012/03/Divideandconquer.png 640w, /wp-content/uploads/2012/03/Divideandconquer-300x188.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption class="wp-caption-text">If it&#039;s too difficult to sort a large list of items, we can break it apart into smaller sub-lists and try to sort them!</figcaption></figure><br />
<span id="more-2847"></span></p>
<h2>Overview</h2>
<p>Merge sort is a comparison model sorting algorithm based on the “divide and conquer” principle. So far so good, so let’s say we have a very large list of data, which we want to sort. Obviously it will be better if we divide the list into two sub-lists with equal length and then sort them. If they remain too large, we can continue breaking them down until we get to something very easy to sort as shown on the diagram bellow.</p>
<figure id="attachment_2859" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/Mergepartinmergesort.png"><img src="/wp-content/uploads/2012/03/Mergepartinmergesort.png" alt="Merge sort is a typical example of divide and conquer technique!" title="Merge part in merge sort" width="620" class="size-full wp-image-2859" srcset="/wp-content/uploads/2012/03/Mergepartinmergesort.png 624w, /wp-content/uploads/2012/03/Mergepartinmergesort-232x300.png 232w" sizes="(max-width: 624px) 100vw, 624px" /></a><figcaption class="wp-caption-text">Merge sort is a typical example of divide and conquer technique!</figcaption></figure>
<p>The thing is that on some step of the algorithm we have two sorted lists and the tricky part is to merge them. However this is not so difficult.<br />
We can start comparing the first items of the lists and than we can pop the smaller of them both and put it into a new list containing the merged (sorted) array.</p>
<h2>Implementation</h2>
<p>The good news is that this algorithm is fast, but not so difficult to implement and that sounds quite good from a developer’s point of view. Here’s the implementation in PHP. Note that every algorithm that follows the divide and conquer principles can be easily implemented in a recursive solution. However recursion can be bitter so you can go for a iterative solution. Typically recursion is &#8220;replaced&#8221; by additional memory space in iterative solutions. Here&#8217;s a recursive version of merge sort.</p>
<pre lang="PHP">
$input = array(6, 5, 3, 1, 8, 7, 2, 4);

function merge_sort($arr)  
{  
	if (count($arr) <= 1) {
		return $arr;  
	}

	$left = array_slice($arr, 0, (int)(count($arr)/2));  
	$right = array_slice($arr, (int)(count($arr)/2));  
	
	$left = merge_sort($left);  
	$right = merge_sort($right);  
	
	$output = merge($left, $right);  

	return $output;  
}  
      
      
function merge($left, $right)  
{  
	$result = array();  

	while (count($left) > 0 && count($right) > 0) {  
		if ($left[0] <= $right[0]) {  
			array_push($result, array_shift($left));  
		} else {  
			array_push($result, array_shift($right));  
		}  
	}  
      
	array_splice($result, count($result), 0, $left);  
	array_splice($result, count($result), 0, $right);  

	return $result;  
}  

// 1, 2, 3, 4, 5, 6, 7, 8
$output = merge_sort($input);
</pre>
<h2>Complexity</h2>
<p>It’s great that the complexity of merge sort is O(n*log(n)) even in the worst case! Note that even quicksort’s complexity can be O(n<sup>2</sup>) in the worst case. So we can be sure that merge sort is very stable no matter the input.</p>
<figure id="attachment_2857" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/mergesortcomplexity.png"><img src="/wp-content/uploads/2012/03/mergesortcomplexity.png" alt="Merge sort complexity is O(n*log(n))" title="merge sort complexity" width="620" class="size-full wp-image-2857" srcset="/wp-content/uploads/2012/03/mergesortcomplexity.png 640w, /wp-content/uploads/2012/03/mergesortcomplexity-300x185.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption class="wp-caption-text">Merge sort complexity is O(n*log(n))</figcaption></figure>
<figure id="attachment_2858" style="width: 481px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/SortingAlgorithmsComplexity.jpg"><img src="/wp-content/uploads/2012/03/SortingAlgorithmsComplexity.jpg" alt="Merge sort complexity is O(n*log(n)) even in the worst case!" title="Sorting Algorithms Complexity" width="481" height="104" class="size-full wp-image-2858" srcset="/wp-content/uploads/2012/03/SortingAlgorithmsComplexity.jpg 481w, /wp-content/uploads/2012/03/SortingAlgorithmsComplexity-300x64.jpg 300w" sizes="(max-width: 481px) 100vw, 481px" /></a><figcaption class="wp-caption-text">Merge sort complexity is O(n*log(n)) even in the worst case!</figcaption></figure>
<h2>Two reasons why merge sort is useful</h2>
<h3>1. Fast no matter the input</h3>
<p>Merge sort is a great sorting algorithm mainly because it’s very fast and stable. It’s complexity is the same even in the worst case and it is O(n*log(n)). Note that even quicksort's complexity is O(n<sup>2</sup>) in the worst case, which for n = 20 is about 4.6 times slower!</p>
<figure id="attachment_2861" style="width: 620px" class="wp-caption alignnone"><a href="/wp-content/uploads/2012/03/mergesortvs.bubblesortforn20.png"><img src="/wp-content/uploads/2012/03/mergesortvs.bubblesortforn20.png" alt="Merge sort is about 4.6 times faster than quicksort for n = 20!" title="mergesort vs. bubble sort for n = 20" width="620" class="size-full wp-image-2861" srcset="/wp-content/uploads/2012/03/mergesortvs.bubblesortforn20.png 640w, /wp-content/uploads/2012/03/mergesortvs.bubblesortforn20-300x120.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></a><figcaption class="wp-caption-text"> </figcaption></figure>
<h3>2. Easy implementation</h3>
<p>Another cool reason is that merge sort is easy to implement. Indeed most of the developer consider something fast to be difficult to implement, but that's not the case of merge sort.</p>
<h2>Three reasons why merge sort is not useful</h2>
<h3>1. Slower than non-comparison based algorithms</h3>
<p>Merge sort is however based on the comparison model and as such can be slower than algorithms non-based on comparisons that can sort data in linear time. Of course, this depends on the input data, so we must be careful for the input.</p>
<h3>2. Difficult to implement for beginners</h3>
<p>Although I don’t think this can be the main reason why not to use merge sort some people say that it can be difficult to implement for beginners, especially the merge part of the algorithm.</p>
<h3>3. Slower than insertion and bubble sort for nearly sorted input</h3>
<p>Again it is very important to know the input data. Indeed if the input is nearly sorted the insertion sort or bubble sort can be faster. Note that in the best case insertion and bubble sort complexity is O(n), while merge sort's best case is O(n*log(n)).</p>
<p>As a conclusion I can say that merge sort is practically one of the best sorting algorithms because it's easy to implement and fast, so it must be considered by every developer!</p>
<div class='yarpp-related-rss'>
<p>Related posts:<ol>
<li><a href="/2012/03/13/computer-algorithms-quicksort/" rel="bookmark" title="Computer Algorithms: Quicksort">Computer Algorithms: Quicksort </a></li>
<li><a href="/2010/07/02/friday-algorithms-javascript-merge-sort/" rel="bookmark" title="Friday Algorithms: JavaScript Merge Sort">Friday Algorithms: JavaScript Merge Sort </a></li>
<li><a href="/2012/02/27/computer-algorithms-shell-sort/" rel="bookmark" title="Computer Algorithms: Shell Sort">Computer Algorithms: Shell Sort </a></li>
<li><a href="/2012/03/19/computer-algorithms-radix-sort/" rel="bookmark" title="Computer Algorithms: Radix Sort">Computer Algorithms: Radix Sort </a></li>
</ol></p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2012/03/05/computer-algorithms-merge-sort/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
