Sunteți pe pagina 1din 7

Home Home > Tutorials > C# > QuickSort in C#

FAQ

About

Contact

View Source

Add to MyHood

SEA RCH:

De vHood

GO

Stats

QuickSort in C#
BROWSE:
My Hood Edit My Info View Events Read Tutorials Training Modules View Presentations Download Tools Scan News Get Jobs Message Forums School Forums Member Directory

[ printer friendly ]

Rating: 4.42 out of 5 by 12 users Submitted: 11/05/02

Ben Watson (dev@benwatson.org)

QuickSort in C# by Be n W a tson Introduction This progra m ste m s from an assignm e nt I did for a class. In e ve ry day use , the re is little re ason to write our own sorting routine s be cause the re are so m any o the r, highlyoptim ize d im ple m e nta tions at our disposal. Howe ve r, unde rstanding one of the faste st and m ost wide ly use d sorting algorithm s out the re is sure to be ne fit any but the m ost casual program m e r. General Procedure Q uick Sort is de signe d to work e fficie ntly on arrays, and it is base d on a divide & conque r a pproach. The ge ne ral ste ps are as follows: 1. C hoose a "pivot" loca tion in the array. 2. Move e ve rything le ss than the pivo t to the le ft part of the array, and e ve rything m ore (or e qual) than it to the right part of the array. 3. Move the pivot ite m to whe re we stoppe d scanning fo r ite m s le ss than it. 4. C all quick sort re cursive ly on the pa rts of the array to e ithe r side of the pivot. 5. W he n the pa rt o f the array we 're so rting is sufficie ntly sm all, call a sim ple r sorting algorithm on the fe w place s le ft, and re turn. Walkthrough example This is e a sie r to se e with an e x am ple : Let's sort the following array of ten integers: [6 24 80 4 19 84 1 10 13 7] Let's choose our pivot to arbitrarily be the first element, a 6. In addition, let's create two pointer iterators to walk through the array looking for things to swap--one from the beginning and the other from the end. We'll call these variable p, m, and n. Thus: p [6 24 80 4 19 84 1 10 13 7] m n If array[m] is greater than array[p] and array[n] is less than array[p] we'll simply swap array[m] and

CONTRIBUTE:
Sign me up! Post an Event Submit Tutorials Upload Tools Link News Post Jobs

array[n]. If one of the conditions matches, and the other doesn't we'll just keep moving the pointers until we can do a swap: p [6 24 80 4 19 84 1 10 13 7] m n Swap: p [6 1 80 4 19 84 24 10 13 7] m n Advance pointers:

C++ Code Quality Unit Testing & Coding Standard Analysis Product
www.parasoft.com

p [6 1 80 4 19 84 24 10 13 7] m n Swap again: p [6 1 4 80 19 84 24 10 13 7] m n Advance pointers: p [6 1 4 80 19 84 24 10 13 7] n m

Free Dream w eaver Training 45 minutes of Free tutorialvideos Stream & Learn Dreamw eaver CS4 tips SFTP com ponents for .NET The fastest and the most pow erful SFTP and SSH components for .NET

Now we see that our pointers have crossed each other. At this point we can safely move our pivot to where n is. This will put the pivot item in its final position in the sorted array: NonLinearEducating.com/Dreamweaver p [4 1 6 80 19 84 24 10 13 7] At this point, everything before p is less than array[p] and everything after p is greater that array[p]. Now we just need to sort both halves. To sort the first half, we don't need to make a call to quicksort--that would be a waste of time since it's only a few elements in length. Instead, we can use a more elementary sorting algorithm, like selection sort, which will yield the following array: p [1 4 6 80 19 84 24 10 13 7] we also need to sort the array after p. For this we will call quicksort recursively on that part. I'll rewrite the array to show only what we're interested in and we'll again choose the first element as the pivot: p [80 19 84 24 10 13 7] m n I've already moved m to the first element greater than array[p], and the last element less than array[p] is the last element in the array. We can then swap those: p [80 19 7 24 10 13 84]

www.eldos.com/SecureBlackbox

You'll notice that there are no more swaps that will occur in this step, and our pointers will cross like this: p [80 19 7 24 10 13 84] n m We can then swap p and n, giving us: p [13 19 7 24 10 80 84] We obviously do not need to sort the right hand side, but the left hand could use a little work: p [13 19 7 24 10] m n p [13 10 7 24 19] m n p [13 10 7 24 19] n m p [7 10 13 24 19] Each side of this can be easily sorted using selection sort (or similar), giving: [7 10 13 19 24] If then look at the whole array we've sorted in pieces, we'll have: [1 4]6[7 10 13 19 24]80[84] -- perfectly sorted!

Ma k e sure you unde rstand the walk -through above , and if you're having trouble unde rstanding wha t's going--work out your own array on pape r--just lik e I did whe n I le arne d this. Code To im ple m e nt this in C #, le t's cre ate our own Array class: public cla ss Array { int[] array; int numItems; public Array(int size) { array=ne w int[size]; numItems=0; } public void Add(int i) { array[numItems++]=i;

} }

This is just the ba sic plum bing to store our value s. W e ne e d to add a function to do our pivoting, or swapping:

private int Pivot(int beg, int end) { //se t pivot to be ginning of array int p=array[beg]; //m also starts at be ginning int m=beg; //n sta rts off e nd (we 'll de cre m e nt it be fore it's use d) int n=end+1; do { m=m+1; } while (array[m]<=p && m&ltend);//find first large r e le m e nt do { n=n-1; } while (array[n] >p);//find last sm alle r e le m e nt //loop until pointe rs cross while (m&ltn) { //swa p int temp=array[m]; array[m]=array[n]; array[n]=temp; //find ne x t value s to swap do { m=m+1; } while (array[m]<=p); do { n=n-1; } while (array[n] >p); } //swa p be ginning with n int temp2=array[n]; array[n]=array[beg]; array[beg]=temp2; re turn n;// n is now the division be twe e n two unsorte d halve s }

Pivot() doe s e x a ctly what I de scribe d in the walk through. The com m e nts should he lp you through the co de . W e also ne e d a function that doe s o ur "sim ple " sorting. I've de cide d to use se le ction sort: private void SelectionSort(int beg, int end) {

for (int { int int for {

i=beg;i&ltend;i++) minj=i; minx=array[i]; (int j=i+1;j<=end;j++) if (array[j]&ltminx) { minj=j; minx=array[j]; }

} array[minj]=array[i]; array[i]=minx; } }

Now tha t we have o ur basic pie ce s, we can cre ate som e controlling functions: public void Sort() { QuickSort(0,array.numItems-1); } private void QuickSort(int beg, int end) { if (end==beg) re turn; if (end-beg&lt9) //an arbitrary lim it to whe n we call se le ctionsort SelectionSort(beg,end); e lse { int l=Pivot(beg,end); QuickSort(beg,l-1); QuickSort(l+1,end); } }

W e m a k e Sort() o ur publically acce ssible m e thod, which calls Q uick Sort() o n the e ntire array. Q uick Sort m ak e s sure the re is e nough array to run on. If the re are fe w e le m e nts, it calls Se le ctionSo rt(), othe rwise , it pivots the array, and calls itse lf on e a ch half. I also cre ate d a public m e thod to dum p the e ntire array to the scre e n so that you can se e the re sults. public void Dump() { foreach(O bje ct o in array) System.Console.Write(o.ToString()+ " "); System.Console.WriteLine(""); }

That's it! It's pre tty e asy once you unde rstand it. The re are lik e ly a num be r of things you can do to optim ize the algorithm e ve n furthe r, but this is the basic fo rm at.

Just to test Use the following code to de m onstrate the Array class a nd Q uick Sort: class MainClass { [STAThread] static int Main(string[] args) { if (args.Length==0) { Console.WriteLine("You must enter an integer to specify array size."); re turn 1; } int size=Convert.ToInt32(args[0]); Array array=ne w Array(size); Random r=ne w Random(); for (int i=0;i&ltsize;i++) array.Add(r.Next(size)); array.Dump(); array.Sort(); array.Dump(); re turn 0; } }

Considerations Q uick Sort runs in O (n log n) tim e , which is ple nty quick , howe ve r the re are two case s which will absolute ly k ill its pe rform a nce . If the array is sorte d in e ithe r asce nding or de sce nding orde r, the n pivot will ne e d to be calle d on e ve ry single e le m e nt (try running through a n e x am ple if you can't se e why that is). The re fore , Q uick Sort is re ally only optim al for arra ys in m ostly random orde r. If it we re possible to se le ct the m e dian as the pivot e ve ry tim e , we could always ge t optim al running tim e , howe ve r this turns out to be a pro ble m that is not wo rth solving in m ost instance s. Pick ing a random e le m e nt, or always the first, e tc. will usually be sufficie ntly fa st.
Return to Brows ing T utorials Rate this Content:
low quality
1 2 3 4 5

E mail this T utorial to a Friend

high quality

Reader's Comments
N ic e tutorial, Ben. * * * * * - - BY U FA N , N ovember 0 7 , 2 0 0 2

Post a C om m e nt

I was jus t thinking to mys elf to write this s ame tutorial while I was in C S c las s . N o need now though, you've definately done a better job of explaining it then I ever c ould, and the C # c ode is c lean and eas y to read. N ic e job! * * * * * - - G eorge Sc hwenzfeger, N ovember 0 8 , 2 0 0 2

QuickSort runs in O(n log n) time A c tually... it's bes t running time is O (nlogn). Wors t c as e is O (n^2 ). I magine the c as e where the pivot is always the minimal element. N ot a big deal, but it s hould be pointed out, if you want guaranteed runtime then you have to be a bit more c areful about your pivot s elec tion, and if you want to guarantee O (nlogn) then you s hould always pic k your pivot to be the median of the s et you are c urrently s orting. - - J ohn G allardo, N ovember 0 8 , 2 0 0 2 V ery good tutorial, c lear and c lean explanation of Q uic kSort. V ery eas y to read c ode... - - G reg M c M urray, N ovember 0 8 , 2 0 0 2 J ohn, many thos e details are pointed out in the c los ing paragraphs of the tutorial. H owever, I did not mention the wors t c as e being O (n^2 ) whic h happens when the array is s orted, s o thanks for pointing that out. - - Ben Wats on, N ovember 0 9 , 2 0 0 2 V ery nic e tutorial, 5 s tars . J us t a few things though: I f you had us ed a random pivot ins tead of the firs t element, then you would make it very very unlikely to reac h the wors t c as e of O (n^2 ). I f you really want to enforc e O (nlogn), you c an eas ily us e heaps ort. T hough the c ons tant is s lightly more than that of a tuned quic ks ort. - - L arry M ak, N ovember 1 5 , 2 0 0 2 N ic e, however, no need to alloc ate temp variable on the s tac k jus t to s wap two values . T hus : int temp=array[m]; array[m]=array[n]; array[n]=temp; C an be written as : array[m] ^= array[n]; array[n] ^= array[m]; array[m] ^= array[n]; -Regards , D avid P ruidze - - D avid P ruidze, D ec ember 1 8 , 2 0 0 2 nlogn tutorial =) - - @ ariel [], A pril 0 2 , 2 0 0 3 D avid, I n the c urrent model of memory, as long as the variable is s mall enough, the ac tual alloc ation of memory is ac tually fas ter than us ing X O R to do s wapping. A t leas t this is us ually the c as e in C with ints .. - - L arry M ak, A pril 2 1 , 2 0 0 3 C ompliments . T he tutorial is written in a nic e and luc id language. - - V inay Bhatia, J une 2 8 , 2 0 0 4

Conditions of Use

Privacy Notice

Copyright 2001 DevHood All Rights Reserved

S-ar putea să vă placă și