Graph Data Structures for Beginners
2018-08-10 09:56
337 查看
Inthispost,wearegoingtoexplorenon-lineardatastructureslikegraphs.Wearegoingtocoverthecentralconceptsandtypicalapplications.
Youareprobablyusingprogramsthatusegraphs(andtrees).Let’ssayforinstancethatyouwanttoknowtheshortestpathbetweenyourworkplaceandhomeyoucanusegraphalgorithmstogettheanswer!Wearegoingtoexplorethisandotherfunchallenges.
Inthepreviouspost,weexplorelineardatastructureslikearrays,linkedlists,sets,stacksandsoon.Thispostbuildsontopofwhatwelearned.
Thispostispartofatutorialseries:
LearningDataStructuresandAlgorithms(DSA)forBeginners
GraphDataStructuresforBeginnersyouarehere
Hereisthesummaryoftheoperationsthatwearegoingtocoveronthispost:
AdjacencyList | AdjacencyMatrix | |
---|---|---|
Space | ||
addVertex | ||
removeVertex | ||
addEdge | ||
removeEdge(usingArray) | ||
removeEdge(usingHashSet) | O(1) | |
getAdjacents | ||
isAdjacent(usingArray) | ||
isAdjacent(usingHashSet) | O(1) |
GraphsBasics
Agraphisadatastructurewhereanodecanhavezeroormoreadjacentelements.Theconnectionbetweentwonodesiscallededge.Nodescanalsobecalledvertices.
Thedegreeisthenumberofedgesconnectedtoavertex.E.g.,the
Iftheedgesarebi-directional,thenwehaveaundirectedgraph.But,iftheedgeshaveadirection,thenwehaveadirectedgraphordi-graphforshort.Youcanthinkofitasaone-waystreet(directed)ortwo-waystreet(undirected).
Vertexcanhaveedgesthatgotoitself(e.g.,
Agraphcanhavecycleswhichmeansthatifyoutraversethroughthenode,youcouldgettothesamenodemorethanonce.Thegraphwithoutcyclesiscalledacyclicgraph.
Also,acyclicundirectedgraphsarecalledtree.Wearegoingtocovertreesindepthinthenextpost.
Notallverticeshavetobeconnectedinthegraph.Youmighthaveisolatednodesorevenseparatedsubgraphs.Ifallnodesarehasaleastoneedge,thenwehaveaconnectedgraph.Whenallnodesareconnectedtoallothernodes,thenwehaveacompletegraph.
Foracompletegraph,eachnodehastohave
GraphApplications
Whenedgeshavevalues/costassignedtothem,wesaywehaveaweightedgraph.Iftheweightisabsent,wecanassumeit’s1.Weightedgraphshavemanyapplicationsdependingonthedomainwhereyouneedtosolveaproblem.Tonameafew:
AirlineTraffic(imageabove)
Node/vertex=Airport
Edges=directflightsbetweentwoairports
Weight=milesbetweentwoairports
GPSNavigation
Node=roadinsersection
Edge=road
Weigth=timerequiredtogofromoneintersectiontoanother
Networksrouting
Node=server
Edge=datalink
Weight=connectionspeed
Ingeneral,graphshavemanyreal-worldapplicationslike:
Electroniccircuits
Flightreservations
Drivingdirections
Telcom:Celltowerfrequencyplanning
Socialnetworks.E.g.,Facebookusesagraphforsuggestingfriends
Recommendations:Amazon/Netflixusesgraphstomakesuggestionsproducts/movies
Graphshelptoplanlogisticsofdeliveringgoods
Wejustlearnedthebasicsofgraphsandsomeapplications.Let’slearnnowhowtorepresentgraphsincode.
Representinggraphs
Threaretwoprimarywaysofrepresentinggraph:Adjacencylist
AdjacencyMatrix
Let’sexplainitwiththefollowingdirectedgraph(digraph)asanexample:
Weadigraphwith4nodes.Whenavertexhaslinktoitself(e.g.
AdjacencyMatrix
Theadjacencymatrixisonewayofrepresentingagraphusingatwo-dimensionalarray(NxNmatrix).Intheintersectionofnodes,weadd1(orotherweight)iftheyareconnectedandUsingthesameexampleasbefore,wecanbuildthefollowingadjacencymatrix:
AdjacencyMatrix
2 3 4 5 | a11--- b--1-- c---1- d-11-- |
It’simportanttonoticethatforundirectedgraphstheadjacencymatrixwillalwaysbesymmetricalbythediagonal.However,that’snotalwaysthecaseonadigraph(likeourexample).
Whatisthetimecomplexityoffindingconnectionsoftwovertices?
QueryingiftwonodesareconnectedinanadjacencymatrixisO(1).
Whatisthespacecomplexity?
StoringagraphasanadjacencymatrixhasaspacecomplexityofO(n2),where
Whatistheruntimetoaddavertex?
Theverticesarestoredasa
AddingavertexonaadjacencymatrixisO(|V|2)
Whataboutgettingtheadjacentnodes?
SincethematrixhasaVxVmatrix,togetalltheadjacentnodestoagivenvertex,wewouldhavetogotothenoderowandgetallitsedgeswiththeothernodes.
Inourpreviousexample,let’ssaywewantalltheadjacentnodesto
2 | b--1-- |
GettingadjacentnodesonanadjacencymatrixisO(|V|)
ImaginethatyouneedtorepresentFacebooknetworkasagraph.Youwouldhavetocreateamatrixof2billionx2billion,wheremostofitwouldbeempty!Nobodywouldknoweverybodyelsejustafewthousandsatmost.
Ingeneral,wedealwithsparsegraphssothematrixwillwastealotofspace.That’swhyinmostimplementationwewoulduseanadjacencylistratherthanthematrix.
AdjacencyList
AdjacencyListisoneofthemostcommonwaystorepresentgraphs.Eachnodehasalistofallthenodesconnectedtoit.GraphscanberepresentedasanadjacencylistusinganArray(orHashMap)containingthenodes.Eachofthisnodeentriesincludesalist(array,linkedlist,set,etc.)thatlistitsadjacentnodes.
Forinstanceinthegraphabovewehavethat
AdjacencyList
2 3 4 | b->{c} c->{d} d->{bc} |
QueryingiftwonodesareconnectedinanadjacencylistisO(n),where
Whataboutthespacecomplexity?
StoringagraphasanadjacencylisthasaspacecomplexityofO(n),where
AdjacencyListGraphHashMapImplementation
Theadjacencylististhemostcommonwayofrepresentinggraphs.Thereareseveralwaystoimplementtheadjacencylist:OneofthemostsimpleisusingaHashMap.The
AdjacencyListasaHashmap
2 3 4 5 6 | a:['a','b'], b:['c'], c:['d'], d:['b','c'] } |
Addandremovevertices
Addandremoveedges
Addingandremovingverticesinvolvesupdatingtheadjacencylist.
Let’ssaythatwewanttoremovethevertex
Everytimeweremoveanode,wewouldhavetoiteratethroughallthenodes’listO(|V|+|E|).Candobetter?Wewillanswerthatlater,firstlet’s*implementourlistinamoreobject-orientedwaysowecanswapimplementationseasily.
AdjacencyListGraphOOImplementation
Let’sstartwiththeNode
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | constructor(value){ this.value=value; this.adjacents=[];//adjacencylist } addAdjacent(node){ this.adjacents.push(node); } removeAdjacent(node){ constindex=this.adjacents.indexOf(node); if(index>-1){ this.adjacents.splice(index,1); returnnode; } } getAdjacents(){ returnthis.adjacents; } isAdjacent(node){ returnthis.adjacents.indexOf(node)>-1; } } |
Makeitwork.Makeitright.Makeitfaster.
Ok,nowthatwehavethe
Graph.constructor
Graph.constructor
2 3 4 5 6 7 8 9 10 | constructor(edgeDirection=Graph.DIRECTED){ this.nodes=newMap(); this.edgeDirection=edgeDirection; } //... } Graph.UNDIRECTED=Symbol('directedgraph');//one-wayedges Graph.DIRECTED=Symbol('undirectedgraph');//two-waysedges |
Graph.addEdge
Twoaddanedgeweneedtwonodes.Oneisthesource,andtheotheristhedestination.
Graph.addEdge
2 3 4 5 6 7 8 9 10 11 12 | constsourceNode=this.addVertex(source); constdestinationNode=this.addVertex(destination); sourceNode.addAdjacent(destinationNode); if(this.edgeDirection===Graph.UNDIRECTED){ destinationNode.addAdjacent(sourceNode); } return[sourceNode,destinationNode]; } |
Theruntimeofaddinganedgefromagraphadjacencylistis:O(1)
Ifwetrytoaddanedgeandthenodesdon’texist,weneedtocreatethemfirst.Let’sdothatnext!
Graph.addVertex
Thewaywecreateanodeisthatweaddittothe
Graph.addVertex
2 3 4 5 6 7 8 9 | if(this.nodes.has(value)){ returnthis.nodes.get(value); }else{ constvertex=newNode(value); this.nodes.set(value,vertex); returnvertex; } } |
Theruntimeofaddingavertexfromagraphadjacencylistis:O(1)
Graph.removeVertex
Removinganodefromthegraph,it’salittlebitmoreinvolved.Wehavetocheckifthenodetobedeletedit’sinuseasanadjacentnode.
Graph.removeVertex
2 3 4 5 6 7 8 9 | constcurrent=this.nodes.get(value); if(current){ for(constnodeofthis.nodes.values()){ node.removeAdjacent(current); } } returnthis.nodes.delete(value); } |
Theruntimeofremovingavertexfromagraphadjacencylistis:O(|V|+|E|)
Finally,let’sremoveimplementremovinganedge!
Graph.removeEdge
Removinganedgeisprettystraightforwardandsimilarto
Graph.removeVertex
2 3 4 5 6 7 8 9 10 11 12 13 14 | constsourceNode=this.nodes.get(source); constdestinationNode=this.nodes.get(destination); if(sourceNode&&destinationNode){ sourceNode.removeAdjacent(destinationNode); if(this.edgeDirection===Graph.UNDIRECTED){ destinationNode.removeAdjacent(sourceNode); } } return[sourceNode,destinationNode]; } |
Iftheverticesdon’texist,wewon’tcreatethem.
Weuse
Since
TheruntimeofremovinganedgefromagraphadjacencylistisO(|E|)
Wearegoingtoexplorehowtosearchvaluesfromanode.
Breadth-frirstsearch(BFS)-Graphsearch
Breadth-firstsearchisawaytonavigateagraphfromaninitialvertexbyvisitingalltheadjacentnodesfirst.Let’sseehowwecanaccomplishthisincode:
Graph.bfs
2 3 4 5 6 7 8 9 10 11 12 13 14 15 | constvisited=newMap(); constvisitList=newQueue(); visitList.add(first); while(!visitList.isEmpty()){ constnode=visitList.remove(); if(node&&!visited.has(node)){ yieldnode; visited.set(node); node.getAdjacents().forEach(adj=>visitList.add(adj)); } } } |
Wearealsousing
ThisanexampleofhowtousetheBFSthatwejustcreated:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | const[first]=graph.addEdge(1,2); graph.addEdge(1,3); graph.addEdge(1,4); graph.addEdge(5,2); graph.addEdge(6,3); graph.addEdge(7,3); graph.addEdge(8,4); graph.addEdge(9,5); graph.addEdge(10,6); bfsFromFirst=graph.bfs(first); bfsFromFirst.next().value.value;//1 bfsFromFirst.next().value.value;//2 bfsFromFirst.next().value.value;//3 bfsFromFirst.next().value.value;//4 //... |
Depth-firstsearch(DFS)-Graphsearch
Depth-firstsearchisanotherwaytonavigateagraphfromaninitialvertexbyrecursivelythefirstadjacentnodeofeachvertexfound.TheiterativeimplementationofaDFSisidenticaltotheBFS,butinsteadofusinga
Graph.dfs
2 3 4 5 6 7 8 9 10 11 12 13 14 15 | constvisited=newMap(); constvisitList=newStack(); visitList.add(first); while(!visitList.isEmpty()){ constnode=visitList.remove(); if(node&&!visited.has(node)){ yieldnode; visited.set(node); node.getAdjacents().forEach(adj=>visitList.add(adj)); } } } |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | const[first]=graph.addEdge(1,2); graph.addEdge(1,3); graph.addEdge(1,4); graph.addEdge(5,2); graph.addEdge(6,3); graph.addEdge(7,3); graph.addEdge(8,4); graph.addEdge(9,5); graph.addEdge(10,6); dfsFromFirst=graph.dfs(first); visitedOrder=Array.from(dfsFromFirst); constvalues=visitedOrder.map(node=>node.value); console.log(values);//[1,4,8,3,7,6,10,2,5,9] |
GraphTimeandSpaceComplexity
WehaveseensomeofthebasicoperationsofaGraph.Howtoaddandremoveverticesandedges.Here’sasummaryofwhatwehavecoveredsofar:AdjacencyList | AdjacencyMatrix | |
---|---|---|
Space | ||
addVertex | ||
removeVertex | ||
addEdge | ||
removeEdge(usingArray) | ||
removeEdge(usingHashSet) | O(1) | |
getAdjacents | ||
isAdjacent(usingArray) | ||
isAdjacent(usingHashSet) | O(1) |
Summary
Aswesaw,Graphscanhelptomodelmanyreal-lifescenariossuchasairports,socialnetworks,internetandsoon.WecoveredsomeofmostbasicalgorithmssuchasBreadth-FirstSearch(BFS)andDepth-FirstSearch(DFS).Also,wetalkaboutimplementationstrade-offssuchasadjacencylistandmatrix.Therearemanyotherapplicationsthatwearegoingtocoverinanotherpostsuchasfindingtheshortestpathbetweennodesanddifferentexcitinggraphalgorithms.相关文章推荐
- 【UESTC】2015 UESTC Training for Data Structures
- Data Analytics for Beginners:第二节
- 2016 UESTC Training for Data Structures O - 卿学姐种美丽的花 树状数组+等差数列
- 2016 UESTC Training for Data Structures C - 卿学姐与诡异村庄 CDOJ 1328 并查集
- UESTC Training for Data Structures——F
- [CareerCup] 10.2 Data Structures for Large Social Network 大型社交网站的数据结构
- 2016 UESTC Training for Data Structures Q - 昊昊爱运动 II 线段树+延迟操作+bitset
- 2016 UESTC Training for Data Structures D - 卿学姐与魔法 CDOJ 1329 堆
- UESTC Training for Data Structures——G
- qscoj 66 ||2017 UESTC Training for Data Structures D(离线+树状数组)
- UESTC_秋实大哥与小朋友 2015 UESTC Training for Data Structures<Problem A>
- 2016 UESTC Training for Data Structures C 卿学姐与诡异村庄
- 2016 UESTC Training for Data Structures R - Japan 树状数组求逆序数
- 2016 UESTC Training for Data Structures E - 卿学姐与城堡的墙 CDOJ 1341 树状数组 逆序对 离散化
- UESTC Training for Data Structures——H
- CDOJ-Training for Data Structures 之K - 方师傅与栈
- UESTC_秋实大哥与花 2015 UESTC Training for Data Structures<Problem B>
- 2016 UESTC Training for Data Structures C -> 卿学姐与诡异村庄 CDOJ 1328 并查集
- 2016 UESTC Training for Data Structures F - 郭大侠与“有何贵干?” CDOJ 1335 线段树 扫描线 离散化
- UESTC Training for Data Structures——I