Академический Документы
Профессиональный Документы
Культура Документы
LinkedLists
Introduction
Onedisadvantageofusingarraystostoredataisthatarraysarestaticstructuresandthereforecannot
beeasilyextendedorreducedtofitthedataset.Arraysarealsoexpensivetomaintainnewinsertions
anddeletions.InthischapterweconsideranotherdatastructurecalledLinkedListsthataddresses
someofthelimitationsofarrays.
Alinkedlistisalineardatastructurewhereeachelementisaseparateobject.
Eachelement(wewillcallitanode)ofalistiscomprisingoftwoitemsthedataandareferenceto
thenextnode.Thelastnodehasareferencetonull.Theentrypointintoalinkedlistiscalledthehead
ofthelist.Itshouldbenotedthatheadisnotaseparatenode,butthereferencetothefirstnode.Ifthe
listisemptythentheheadisanullreference.
Alinkedlistisadynamicdatastructure.Thenumberofnodesinalistisnotfixedandcangrowand
shrinkondemand.Anyapplicationwhichhastodealwithanunknownnumberofobjectswillneedto
usealinkedlist.
Onedisadvantageofalinkedlistagainstanarrayisthatitdoesnotallowdirectaccesstothe
individualelements.Ifyouwanttoaccessaparticularitemthenyouhavetostartattheheadand
followthereferencesuntilyougettothatitem.
Anotherdisadvantageisthatalinkedlistusesmorememorycomparewithanarrayweextra4bytes
(on32bitCPU)tostoreareferencetothenextnode.
TypesofLinkedLists
Asinglylinkedlistisdescribedabove
Adoublylinkedlistisalistthathastworeferences,onetothenextnodeandanothertoprevious
node.
Anotherimportanttypeofalinkedlistiscalledacircularlinkedlistwherelastnodeofthelistpoints
backtothefirstnode(orthehead)ofthelist.
TheNodeclass
InJavayouareallowedtodefineaclass(say,B)insideofanotherclass(say,A).TheclassAiscalled
theouterclass,andtheclassBiscalledtheinnerclass.Thepurposeofinnerclassesispurelytobe
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 1/7
5/5/2017 LinkedLists
usedinternallyashelperclasses.HereistheLinkedListclasswiththeinnerNodeclass
privatestaticclassNode<AnyType>
{
privateAnyTypedata
privateNode<AnyType>next
publicNode(AnyTypedata,Node<AnyType>next)
{
this.data=data
this.next=next
}
}
Aninnerclassisamemberofitsenclosingclassandhasaccesstoothermembers(inclusingprivate)
oftheouterclass,Andviseversa,theouterclasscanhaveadirectaccesstoallmembersoftheinner
class.Aninnerclasscanbedeclaredprivate,public,protected,orpackageprivate.Therearetwokind
ofinnerclasses:staticandnonstatic.Astaticinnerclasscannotreferdirectlytoinstancevariablesor
methodsdefinedinitsouterclass:itcanusethemonlythroughanobjectreference.
WeimplementtheLinkedListclasswithtwoinnerclasses:staticNodeclassandnonstatic
LinkedListIteratorclass.SeeLinkedList.javaforacompleteimplementation.
Examples
Letusassumethesinglylinkedlistaboveandtracedowntheeffectofeachfragmentbelow.Thelist
isrestoredtoitsinitialstatebeforeeachlineexecutes
1. head=head.next
2. head.next=head.next.next
3. head.next.next.next.next=head
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 2/7
5/5/2017 LinkedLists
LinkedListOperations
addFirst
Themethodcreatesanodeandprependsitatthebeginningofthelist.
publicvoidaddFirst(AnyTypeitem)
{
head=newNode<AnyType>(item,head)
}
Traversing
Startwiththeheadandaccesseachnodeuntilyoureachnull.Donotchangetheheadreference.
Nodetmp=head
while(tmp!=null)tmp=tmp.next
addLast
Themethodappendsthenodetotheendofthelist.Thisrequirestraversing,butmakesureyoustopat
thelastnode
publicvoidaddLast(AnyTypeitem)
{
if(head==null)addFirst(item)
else
{
Node<AnyType>tmp=head
while(tmp.next!=null)tmp=tmp.next
tmp.next=newNode<AnyType>(item,null)
}
}
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 3/7
5/5/2017 LinkedLists
Inserting"after"
Findanodecontaining"key"andinsertanewnodeafterit.Inthepicturebelow,weinsertanewnode
after"e":
publicvoidinsertAfter(AnyTypekey,AnyTypetoInsert)
{
Node<AnyType>tmp=head
while(tmp!=null&&!tmp.data.equals(key))tmp=tmp.next
if(tmp!=null)
tmp.next=newNode<AnyType>(toInsert,tmp.next)
}
Inserting"before"
Findanodecontaining"key"andinsertanewnodebeforethatnode.Inthepicturebelow,weinserta
newnodebefore"a":
Forthesakeofconvenience,wemaintaintworeferencesprevandcur.Whenwemovealongthelist
weshiftthesetworeferences,keepingprevonestepbeforecur.Wecontinueuntilcurreachesthe
nodebeforewhichweneedtomakeaninsertion.Ifcurreachesnull,wedon'tinsert,otherwisewe
insertanewnodebetweenprevandcur.
Examinethisimplementation
publicvoidinsertBefore(AnyTypekey,AnyTypetoInsert)
{
if(head==null)returnnull
if(head.data.equals(key))
{
addFirst(toInsert)
return
}
Node<AnyType>prev=null
Node<AnyType>cur=head
while(cur!=null&&!cur.data.equals(key))
{
prev=cur
cur=cur.next
}
//insertbetweencurandprev
if(cur!=null)prev.next=newNode<AnyType>(toInsert,cur)
}
Deletion
Findanodecontaining"key"anddeleteit.Inthepicturebelowwedeleteanodecontaining"A"
Thealgorithmissimilartoinsert"before"algorithm.Itisconvinienttousetworeferencesprevand
cur.Whenwemovealongthelistweshiftthesetworeferences,keepingprevonestepbeforecur.
Wecontinueuntilcurreachesthenodewhichweneedtodelete.Therearethreeexceptionalcases,
weneedtotakecareof:
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 4/7
5/5/2017 LinkedLists
1.listisempty
2.deletetheheadnode
3.nodeisnotinthelist
publicvoidremove(AnyTypekey)
{
if(head==null)thrownewRuntimeException("cannotdelete")
if(head.data.equals(key))
{
head=head.next
return
}
Node<AnyType>cur=head
Node<AnyType>prev=null
while(cur!=null&&!cur.data.equals(key))
{
prev=cur
cur=cur.next
}
if(cur==null)thrownewRuntimeException("cannotdelete")
//deletecurnode
prev.next=cur.next
}
Iterator
Thewholeideaoftheiteratoristoprovideanaccesstoaprivateaggregateddataandatthesame
momenthidingtheunderlyingrepresentation.AniteratorisJavaisanobject,andthereforeit's
implementationrequirescreatingaclassthatimplementstheIteratorinterface.Usuallysuchclassis
implementedasaprivateinnerclass.TheIteratorinterfacecontainsthefollowingmethods:
AnyTypenext()returnsthenextelementinthecontainer
booleanhasNext()checksifthereisanextelement
voidremove()(optionaloperation).removestheelementreturnedbynext()
InthissectionweimplementtheIteratorintheLinkedListclass.Firstofallweaddanewmethodto
theLinkedListclass:
publicIterator<AnyType>iterator()
{
returnnewLinkedListIterator()
}
HereLinkedListIteratorisaprivateclassinsidetheLinkedListclass
privateclassLinkedListIteratorimplementsIterator<AnyType>
{
privateNode<AnyType>nextNode
publicLinkedListIterator()
{
nextNode=head
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 5/7
5/5/2017 LinkedLists
}
...
}
TheLinkedListIteratorclassmustprovideimplementationsfornext()andhasNext()methods.
Hereisthenext()method:
publicAnyTypenext()
{
if(!hasNext())thrownewNoSuchElementException()
AnyTyperes=nextNode.data
nextNode=nextNode.next
returnres
}
Cloning
Likeforanyotherobjects,weneedtolearnhowtoclonelinkedlists.Ifwesimplyusetheclone()
methodfromtheObjectclass,wewillgetthefollowingstructurecalleda"shallow"copy:
TheObject'sclone()willcreateacopyofthefirstnode,andsharetherest.Thisisnotexactlywhatwe
meanby"acopyoftheobject".Whatweactuallywantisacopyrepresentedbythepicturebelow
Sinceoutdataisimmutableit'soktohavedatasharedbetweentwolinkedlists.Thereareafewideas
toimplementlinkedlistcopying.Thesimplestoneistotraversetheoriginallistandcopyeachnode
byusingtheaddFirst()method.Whenthisisfinished,youwillhaveanewlistinthereverseorder.
Finally,wewillhavetoreversethelist:
publicObjectcopy()
{
LinkedList<AnyType>twin=newLinkedList<AnyType>()
Node<AnyType>tmp=head
while(tmp!=null)
{
twin.addFirst(tmp.data)
tmp=tmp.next
}
returntwin.reverse()
}
Abetterwayinvolvesusingatailreferenceforthenewlist,addingeachnewnodeafterthelastnode.
publicLinkedList<AnyType>copy3()
{
if(head==null)returnnull
LinkedList<AnyType>twin=newLinkedList<AnyType>()
Nodetmp=head
twin.head=newNode<AnyType>(head.data,null)
NodetmpTwin=twin.head
while(tmp.next!=null)
{
tmp=tmp.next
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 6/7
5/5/2017 LinkedLists
tmpTwin.next=newNode<AnyType>(tmp.data,null)
tmpTwin=tmpTwin.next
}
returntwin
}
Applications
PolynomialAlgebra
Thebiggestintegerthatwecanstoreinavariableofthetypeintis2311on32butCPU.Youcan
easilyverifythisbythefollowingoperations:
intprod=1
for(inti=1i<=31i++)
prod*=2
System.out.println(prod)
Thiscodedoesn'tproduceanerror,itproducesaresult!Theprintedvalueisanegativeinteger
2147483648=231.Ifthevaluebecomestoolarge,Javasavesonlytheloworder32(or64for
longs)bitsandthrowstherestaway.
Inreallifeapplicationsweneedtodealwithintegersthatarelargerthan64bits(thesizeofalong).
Tomanipulatewithsuchbignumbers,wewillbeusingalinkedlistdatastructure.Firstweobserve
thateachintegercanbeexpressedinthedecimalsystemofnotation.
937=9*102+3*101+7*100
2011=2*103+0*102+1*101+1*100
Now,ifwereplaceadecimalbase10byacharacter,say'x',weobtainaunivariatepolynomial,such
as
0.451.89x2+3.4x5+9x16
Wewillwriteanapplicationthatmanipulatespolynomialsinonevariablewithreal
coefficients.Amongmanyoperationsonpolynomials,weimplementaddition,multiplication,
differentiationandevaluation.Apolynomialwillberepresentedasalinkedlist,whereeachnodehas
anintegerdegree,adoublecoefficientandareferencetothenextterm.Thefinalnodewillhaveanull
referencetoindicatetheendofthelist.Hereisalinkedlinkrepresentationfortheabovepolynomial:
Thetermsarekeptinorderfromsmallesttolargestexponent.SeePolynomial.javafordetails.
VictorS.Adamchik,CMU,2009
https://www.cs.cmu.edu/~adamchik/15121/lectures/Linked%20Lists/linked%20lists.html 7/7