<?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>Brian Paden&#039;s somewhat technical blog &#187; big O notation</title>
	<atom:link href="http://www.college-code.com/blog/tag/big-o-notation/feed" rel="self" type="application/rss+xml" />
	<link>http://www.college-code.com/blog</link>
	<description>The mostly tech related musings of a Software Engineering grad student</description>
	<lastBuildDate>Tue, 04 May 2010 06:38:52 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Big O Notation</title>
		<link>http://www.college-code.com/blog/2008/big-o-notation</link>
		<comments>http://www.college-code.com/blog/2008/big-o-notation#comments</comments>
		<pubDate>Tue, 06 May 2008 00:14:17 +0000</pubDate>
		<dc:creator>Brian Paden</dc:creator>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[big O notation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.college-code.com/blog/?p=12</guid>
		<description><![CDATA[It is time for a primer on big o. No, not that Big O. I am talking about the one we use in computer science. (If you don&#8217;t undestand the picture it is from an anime called The Big O) What is big o notation? Big O notation is a method used in computer science, [...]]]></description>
			<content:encoded><![CDATA[<p>It is time for a primer on big o.<br />
<a href="http://www.college-code.com/blog/wp-content/uploads/2008/05/the-big-o.jpg"><img class="size-medium wp-image-13" style="vertical-align: middle;" title="the-big-o" src="http://www.college-code.com/blog/wp-content/uploads/2008/05/the-big-o.jpg" alt="Big O" width="400" height="373" /></a></p>
<p>No, not that Big O. I am talking about the one we use in computer science. (If you don&#8217;t undestand the picture it is from an anime called <a href="http://en.wikipedia.org/wiki/The_Big_O" target="_blank">The Big O</a>)</p>
<h2>What is big o notation?</h2>
<p>Big O notation is a method used in computer science, and mathematics, to describe the efficiency of an algorithm. There are several other notations but big o is the most common for computer science. In short it is a function that describes the worst case performance of an algorithm. Big o means given <strong>n</strong> inputs the algorithm uses O(<strong>x</strong>), pronounced O of x, resources. <strong>x</strong> is a function that depends on <strong>n</strong>. Generally we are measuring operations, and thus speed, but it can also be used for memory usage or many other metrics.  Big o is useful because it tells us the algorithm will never be any worse than this. Little o tells you it can never be better than this and theta notation says it will be in this family, but those are beyond the scope of this post.</p>
<h2>Figuring out big o</h2>
<p>Actually proving some algorithm belongs to a certain set of big o families is not always easy but it is usually pretty simple to ballpark it. There are several commonly used types that we will cover.</p>
<h3>Constant Time</h3>
<p>Let&#8217;s look at a simple function, it just returns a value from an array given the index.  All the examples are going to be in C++, just a forewarning.</p>
<p style="PADDING-LEFT: 30px">int getIndex( int Data[], int Index )<br />
{<br />
   return Data[Index];<br />
}</p>
<p>This will take the same amount of time no matter what values we give it. We call this constant time or O(1). Now for a more interesting example.</p>
<h3>Logarithmic Time</h3>
<p>Logarithmic time is most often found where you partition the data into two even parts then continue working on one of them.  Binary search is a good example of this, it looks for a value in a sorted array.  It chooses a pivot value in the middle, determines if the value it is looking for is above or below the pivot then starts the search again using the new partition.</p>
<p style="padding-left: 30px;">int binarySearch(int sortedArray[], int first, int last, int key) {<br />
   while (first &lt;= last) {<br />
      int mid = (first + last) / 2; // compute mid point.<br />
      if (key &gt; sortedArray[mid])<br />
         first = mid + 1; // repeat search in top half.<br />
      else if (key &lt; sortedArray[mid])<br />
         last = mid &#8211; 1; // repeat search in bottom half.<br />
      else<br />
         return mid; // found it. return position /////<br />
   }<br />
return -(first + 1); // failed to find key<br />
}</p>
<p>The proof showing that the relation between amount of work down and the number of inputs is not trivial so I will just say that these types of algorithms are classified as O(log n).  (Look up <a href="http://en.wikipedia.org/wiki/Master_theorem" target="_blank">master theorem</a> if you need more nitty gritty)  Technically it should be log base 2 n but few people complain if you just say log n.</p>
<h3>Linear Time</h3>
<p>Here is a function that takes an array of ints and prints them out.</p>
<p style="PADDING-LEFT: 30px">void printInts( int Data[], int Size )<br />
{<br />
   for( int i = 0; i &lt; Size; i++ )<br />
   {<br />
      std::cout &lt;&lt; Data[i] &lt;&lt; std::endl;<br />
   }<br />
}</p>
<p>We would say that Size is <strong>n</strong> because that is how many elements we have to look at. Since there is no way to get the job done without printing each of the n elements this is O(n) or linear time.</p>
<h3>Polynomial</h3>
<p>If you take a loop that is called n times and place a loop that does an additional n work what do you get? You get polynomial time.</p>
<p style="padding-left: 30px;">void printAll( int Data[][], int SizeOne, int SizeTwo )<br />
{<br />
   for( int i = 0; i &lt; SizeOne; i++ )<br />
   {<br />
      for( int j = 0; j &lt; SizeTwo; j++ )<br />
      {<br />
         std::cout &lt;&lt; Data[i][j] &lt;&lt; &#8221; &#8220;;<br />
      }<br />
      std::cout &lt;&lt; std::endl;<br />
   }<br />
}</p>
<p>If we say SizeOne is n and SizeTwo is m, then we do n work, but each n work consists of m work as well. So we have to do n*m work. If n = m we would get n*n or n^2 work. Polynomial time is anything of the form n^m, where m doesn&#8217;t have to be an integer but it is greater than one. O(n^2) is referred to as quadratic because it appears often enough to get a special name.  This is written as O(n^2), O(n^3), etc.</p>
<h3>Others</h3>
<p>Exponential is O(c^n), where c is some some constant value. Examples that use this would be the traveling salesman problem, a notoriously hard problem in computing.</p>
<p>N to the n is O(n^n), something you should avoid writing if at all possible. These are slow. And by slow I mean the universe will end before this code finishes running.</p>
<p>In summary here are the most common forms and their names.<br />
<a href="http://www.college-code.com/blog/wp-content/uploads/2008/05/big_o_table.png"><img class="size-medium wp-image-14" style="vertical-align: middle;" title="big_o_table" src="http://www.college-code.com/blog/wp-content/uploads/2008/05/big_o_table.png" alt="Big O Notation table" width="376" height="170" /></a></p>
<h2>Why You Care</h2>
<p>If each operation takes one second, then with n at 1 million this is how long it takes for each of the common ones to run.</p>
<p><img class="aligncenter size-medium wp-image-15" title="big_o_times" src="http://www.college-code.com/blog/wp-content/uploads/2008/05/big_o_times.png" alt="Big O Timing" width="171" height="105" /></p>
<p>It should be obvious from the chart that a small change in the big o value of your algorithm can make a huge difference in computation time.  For most problems you can find something that is polynomial or better, log-linear being the best you can get for many problems.</p>
<p>Big o is also the worst case performance.  So getting O(n^2) may only occur when all the ducks are in a row, average case may be O(n log n) which is much faster for large n.  Another thing to consider is while many algorithms may have the same big o implementations affect performance as well.  So for small data sets a lean O(n^2) algorithm may out perform a O(n log n) one that has large amounts of overhead.  All things to keep in mind when you are writing code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.college-code.com/blog/2008/big-o-notation/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

