<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<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/"
	>

<channel>
	<title>quickselect &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://wordpress.com/tag/quickselect/</link>
	<description>Feed of posts on WordPress.com tagged "quickselect"</description>
	<pubDate>Thu, 21 Aug 2008 07:01:55 +0000</pubDate>

	<generator>http://wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Quickselect]]></title>
<link>http://fripp.wordpress.com/?p=117</link>
<pubDate>Thu, 08 May 2008 09:00:15 +0000</pubDate>
<dc:creator>fripp</dc:creator>
<guid>http://fripp.wordpress.com/?p=117</guid>
<description><![CDATA[Il Quickselect è un algoritmo randomizzato ricorsivo che trova l&#8217;elemento che si troverebbe i]]></description>
<content:encoded><![CDATA[<p>Il Quickselect è un algoritmo randomizzato ricorsivo che trova l'elemento che si troverebbe in k-esima posizione se l'array in cui si trova fosse ordinato.</p>
<p>Su un array di grandezza  $latex n$ l'algoritmo esegue $latex O(n^2)$ confronti nel caso peggiore e $latex O(n)$ nel caso atteso. Si basa sull'algoritmo Quicksort.</p>
<p>L'idea di base che sta alla base dell'algoritmo è molto semplice: se si deve estrarre l'elemento che si troverebbe in k-esima posizione se l'array fosse ordinato, basta ordinare di volta in volta la porzione dell'array in cui l'elemento si troverebbe, trascurando il resto dell'array.</p>
<p>Ecco un'implementazione in C di questo algoritmo:<br />
<!--more--></p>
<p>[sourcecode language="C"]<br />
inline int partition(int *v, int i, int f){<br />
	int x=v[i];<br />
	int inf=i;<br />
	int sup=f+1;<br />
	while(1){<br />
		do<br />
			inf++;<br />
		while(v[inf]<=x && inf<=f);</p>
<p>		do<br />
			sup--;<br />
		while(v[sup]>x);</p>
<p>		if(inf<sup)<br />
			swap(v+inf,v+sup);<br />
		else<br />
			break;<br />
	}</p>
<p>	swap(v+i,v+sup);</p>
<p>	inf=i;<br />
	int s=sup+1;</p>
<p>	while(1){<br />
		do<br />
			inf++;<br />
		while(v[inf]!=x && inf<=f);</p>
<p>		do<br />
			s--;<br />
		while(v[s]==x);</p>
<p>		if(inf<s)<br />
			swap(v+inf,v+s);<br />
		else<br />
			break;<br />
	}</p>
<p>	return sup;<br />
}</p>
<p>inline int quickselect(int *v, int l, int r, int k){</p>
<p>	if(l>=r)<br />
		return v[k];<br />
	int p=partition(v,l,r);</p>
<p>	int dim=p;</p>
<p>	while(v[dim]==v[p]  && dim>l)<br />
		dim--;</p>
<p>	if(k>dim && k<=p)<br />
		return v[p];</p>
<p>	if(k<=dim)<br />
		return quickselect(v,l,dim,k);</p>
<p>	return quickselect(v,p+1,r,k);</p>
<p>}<br />
[/sourcecode]</p>
<p>La funzione di partizionamento è uguale a quella implementata nel caso del quicksort generico presentato in <a href="http://fripp.wordpress.com/2007/11/28/generic-quicksort/">questo</a> post.</p>
<p>In questo caso, a differenza della precedente versione, facciamo in modo che tutti gli elementi uguali al pivot si trovino tutti vicini (ultimo ciclo <em>while</em> del codice).</p>
<p>La funzione <em>quickselect </em>sceglie ad ogni passo ricorsivo quale porzione dell'array ordinare, in base al valore del parametro <em>k</em> passato come argomento.</p>
]]></content:encoded>
</item>

</channel>
</rss>
