Вы находитесь на странице: 1из 7

5/5/2017 LinkedLists

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

Вам также может понравиться