Sunteți pe pagina 1din 4

24/9/2016

QuickSortonLists

QuickSortonLists
QuickSort
Quicksortisanothersortingalgorithm,similartomergesort.Itwasdiscoveredbythecomputerscientist
TonyHoare.Hereisthebasisofthequicksortalgorithmtosortanycollectionofdata:
Pickoutoneitemfromthedata,whichiscalledthepivot
Dividethecollectionintotwocollections,oneallthoseitemslessthanthepivotacordingtothe
oderingyouareusing,theotherallthoseitemsgreaterthanit
Sortthetwocollections(recursively,thebasecasebeingthatifacollectionisempty,itisalready
sorted)intotwoorderedcollections
Appendthetwoorderedcollectionswiththepivotinbetweenthem
Nowwehaveacompletelyorderedcollectioncontainingthesameelementsastheoriginal
Forexample,supposewewanttosortthelist[14,12,9,17,22,20,8,6,25,5,3].Wechoosethefirstelementof
thislist,14asthepivotanddivideitintotwolists,oneofallthoseelementslessthan14,theotherallthose
greaterthan14,sowehave[12,9,8,6,5,3]and[17,22,20,25].Wethensortbothofthoselists,givingus
[3,5,6,8,9,12]and[17,20,22,25].Wethenjointhemtogether,with14inthemiddle,givingus
[3,5,6,8,9,12,17,20,22,25].
Quicksortisrathercomplicatedwhendonewitharrays,sincewedon'tknowinadvancehowmanyelements
willbelessthanthepivotandhowmanygreater.Itcanbedone,however,andyoucanseecodeforitin
manyalgorithmsanddatastructurestextbooks.Itwasinordertoavoidthiscomplexity,however,thatinthis
coursewecoveredmergesortasanexampleofanO(nlogn)sortingalgorithmratherthanquicksort,which
isalsoO(nlogn).
Withmergesortweknowthesizeofthetwocollectionswearedividingtheoriginalintowillbehalfthesize
oftheoriginal.Withquicksortthisisnotnecessarilythecase,inourexampleabovethelistwasdividedinto
twolists,oneoflength6theotheroflength4,nottwooflength5.Inmergesort,mostoftheworkofsorting,
thecomparisonofelementsisdoneaftertherecursivecallswhenthetwosortedcollectionsaremerged.With
quicksortthecomparisonsaredonebeforetherecursivecallsasthecollectionisdividedintotwoparts.
Quicksortismostefficientwhenthedivision(or"partition"asitisusuallycalled)dividesthecollectioninto
tworoughlyequalparts.Ifithappenedthatthenumberwechoseasthepivotwhensortingcollectionof
integersintoascendingorderwasthesmallestnumberinthecollection,ourpartitionwouldbeintotwo
collections,oneempty,andtheotheronlyonelessinsizethantheoriginalcollection.Forthisreason,
althoughthefirstnumberinacollectionisoftenchosenasthepivot,thisisabadchoiceifthecollectionis
ordered,andinsomeversionsofquicksortamoreelaboratechoiceofpivotismade.
Quicksortiseasytocodewhenwearedealingwithlists.Belowisamethodforsortingalistofintegers
usingquicksort,togetherwithamainmethodfordemonstratingit:
importjava.io.*;
classUseLists2
{
publicstaticvoidmain(String[]args)
throwsIOException
{
BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));
Stringstr;
Listl1,l2;
System.out.println("Enteralist:");
str=in.readLine();
l1=List.fromString(str);
l2=quickSort(l1);
System.out.println("Sortingthelistgives:");
System.out.println(l2);
http://www.eecs.qmul.ac.uk/~mmh/DCS128/2006/resources/quicksortlists.html

1/4

24/9/2016

QuickSortonLists

}
publicstaticListappend(Listl1,Listl2)
{
if(l1.isEmpty())
returnl2;
else
returnappend(l1.tail(),l2).cons(l1.head());
}
publicstaticListgreaterThan(intn,Listl)
{
if(l.isEmpty())
returnList.empty();
else
{
inth=l.head();
Listr=greaterThan(n,l.tail());
if(h>n)
returnr.cons(h);
else
returnr;
}
}
publicstaticListlessThanOrEq(intn,Listl)
{
if(l.isEmpty())
returnList.empty();
else
{
inth=l.head();
Listr=lessThanOrEq(n,l.tail());
if(h<=n)
returnr.cons(h);
else
returnr;
}
}
publicstaticListquickSort(Listl)
{
if(l.isEmpty())
returnList.empty();
else
{
intp=l.head();
Listt=l.tail();
Lists=quickSort(lessThanOrEq(p,t));
Listg=quickSort(greaterThan(p,t));
returnappend(s,g.cons(p));
}
}
}

Hereweusetwoseparatemethodstopartitiontheoriginallist,onegivesalistofallelementslessthanor
equal(thisaccountsforduplicatesofthepivot)thanthepivot,theotheralistofallelementsgreaterthanthe
pivot.Itwouldbepreferabletohaveonemethodwhichjustwentthroughthelistoncereturningbothlists,
butaJavamethodcanonlyreturnonevalue.

Amoreefficientquicksortprogram
TherearewaysofgettingroundtheproblemmentionedabovethataJavamethodcanonlyreturnonevalue
whereaswewantedapartitionmethodthanreturnedtwolists,butwewon'tdiscussthemhere.Asimpler
thingwouldbejusttoputthecodeforpartioningtheoriginallistaspartofthecodeforthemethod
quickSortratherthanasaseparatemethod.Alsotheorderingofthetwoliststheoriginalisdividedinto
doesn'tmatter,sowecoulduseiterationandendupwiththeminthereverseoftheiroriginalorderwithout
http://www.eecs.qmul.ac.uk/~mmh/DCS128/2006/resources/quicksortlists.html

2/4

24/9/2016

QuickSortonLists

thataffectingtheresult.Iterationismoreefficientthanrecursionbecauseitdoesn'tinvolvetheextraworkof
arrangingformethodcalls.
Anotherimprovementwecanmakeonourquicksortalgorithmremovestheuseoftheappendmethod.This
usesanideaknownasconcatenationeliminationdescribedbythecomputerscientistPhilWadler.Theidea
wasdevelopedinthecontextoffunctionalprogramming.TheintroductionoftheabstractdatatypeList
enablesustoprogramintheJavalanguageinastylewhichresemblesfunctionalprogramming.
Whenwequicksorttwolistsanduseappendtojointhemtogether,wehavetorunrightthroughthefirstlist
toitsendtojoinittothesecond.Withourconstructivelists,appendingthefirsttothesecondactually
involvescopyingtheentirefirstlist.However,ifwejoinedthesortedversionofthefirstlisttothesorted
versionofthesecondlistasweconstructedit,wewouldn'thavetoappenditafterwards.Soweusea
variationofquicksortwhichtakestwoparameters,landaccandreturnsthesortoflappendedontoacc.
Justtoquicksortalist,wecallthiswithaccsettotheemptylist.
BelowisthemoreefficientquickSortwiththepartitionofthelistdonebyiterationaspartofthequickSort
methodratherthanbyrecursioninaseparatemethod,andusingWadler'svariationofquicksort.Thereisalso
amainmethodtoenableittobedemonstrated,butofcourseitisnodifferentfromthemainmethodbefore.
importjava.io.*;
classUseLists3
{
publicstaticvoidmain(String[]args)
throwsIOException
{
BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));
Stringstr;
Listl1,l2;
System.out.println("Enteralist:");
str=in.readLine();
l1=List.fromString(str);
l2=quickSort(l1);
System.out.println("Sortingthelistgives:");
System.out.println(l2);
}
publicstaticListquickSort(Listl)
{
returnquickSort(l,List.empty());
}
privatestaticListquickSort(Listl,Listacc)
{
if(l.isEmpty())
returnacc;
else
{
intp=l.head();
Lists=List.empty();
Listg=List.empty();
for(l=l.tail();!l.isEmpty();l=l.tail())
{
inth=l.head();
if(h>p)
g=g.cons(h);
else
s=s.cons(h);
}
l=quickSort(g,acc);
returnquickSort(s,l.cons(p));
}
}
}
http://www.eecs.qmul.ac.uk/~mmh/DCS128/2006/resources/quicksortlists.html

3/4

24/9/2016

QuickSortonLists

Wecanmakethisevenmoreefficientbynotingthatwenowhaveamethodwhichistailrecursive,thatisthe
valueitreturnsisgivendirectlybyarecursivecall.Wecantransformtailrecursivemethodsintoiterative
methods,anddoingthisontheabovequickSortmethodgivesus:
privatestaticListquickSort(Listl,Listacc)
{
while(!l.isEmpty())
{
intp=l.head();
Lists=List.empty();
Listg=List.empty();
for(l=l.tail();!l.isEmpty();l=l.tail())
{
inth=l.head();
if(h>p)
g=g.cons(h);
else
s=s.cons(h);
}
acc=quickSort(g,acc).cons(p);
l=s;
}
returnacc;
}
}

Themethodisstillrecursive,becausetheoriginalmethodhadtworecursivecalls.Now,however,thereis
onlyonerecursivecallbecausethesecondonehasbeentransformedintoiteration.Thecostofincreasingthe
efficiencyoftheprogramisthatthecodeisnolongersoeasytounderstand.Ourinitialcodeforquicksort
wasalmostadirecttranslationofthealgorithmtocode,sothatonceyouarehappywithrecursionyoudonot
havetodoanythingmoretoconvinceyourselfitwillwork.Ourfinalcodeisnotnearlysoclear.
MatthewHuntbach
Lastmodified:11March2005

http://www.eecs.qmul.ac.uk/~mmh/DCS128/2006/resources/quicksortlists.html

4/4

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