packageedu.princeton.cs.algs4;publicclassCC{privateboolean[]marked;// marked[v] = has vertex v been marked?privateint[]id;// id[v] = id of connected component containing vprivateint[]size;// size[id] = number of vertices in given componentprivateintcount;// number of connected componentspublicCC(GraphG){marked=newboolean[G.V()];id=newint[G.V()];size=newint[G.V()];for(intv=0;v<G.V();v++){if(!marked[v]){dfs(G,v);count++;}}}// depth-first search for a Graphprivatevoiddfs(GraphG,intv){marked[v]=true;id[v]=count;size[count]++;for(intw:G.adj(v)){if(!marked[w]){dfs(G,w);}}}publicintid(intv){returnid[v];}publicintsize(intv){returnsize[id[v]];}publicintcount(){returncount;}// are the two vertices connected?publicbooleanconnected(intv,intw){returnid(v)==id(w);}}
packageedu.princeton.cs.algs4;publicclassEulerianCycle{privateStack<Integer>cycle=newStack<Integer>();// Eulerian cycle; null if no such cycle// an undirected edge, with a field to indicate whether the edge has already been usedprivatestaticclassEdge{privatefinalintv;privatefinalintw;privatebooleanisUsed;publicEdge(intv,intw){this.v=v;this.w=w;isUsed=false;}// returns the other vertex of the edgepublicintother(intvertex){if(vertex==v)returnw;elseif(vertex==w)returnv;elsethrownewIllegalArgumentException("Illegal endpoint");}}// computes an Eulerian cycle in the specified graph, if one existspublicEulerianCycle(GraphG){// must have at least one edgeif(G.E()==0)return;// necessary condition: all vertices have even degree// (this test is needed, or it might find an Eulerian path instead of cycle)for(intv=0;v<G.V();v++)if(G.degree(v)%2!=0)return;// create local view of adjacency lists, to iterate one vertex at a time// the helper Edge data type is used to avoid exploring both copies of an edge v-wQueue<Edge>[]adj=(Queue<Edge>[])newQueue[G.V()];for(intv=0;v<G.V();v++)adj[v]=newQueue<Edge>();for(intv=0;v<G.V();v++){intselfLoops=0;for(intw:G.adj(v)){// careful with self loopsif(v==w){if(selfLoops%2==0){Edgee=newEdge(v,w);adj[v].enqueue(e);adj[w].enqueue(e);}selfLoops++;}elseif(v<w){Edgee=newEdge(v,w);adj[v].enqueue(e);adj[w].enqueue(e);}}}// initialize stack with any non-isolated vertexints=nonIsolatedVertex(G);Stack<Integer>stack=newStack<Integer>();stack.push(s);// greedily search through edges in iterative DFS stylecycle=newStack<Integer>();while(!stack.isEmpty()){intv=stack.pop();while(!adj[v].isEmpty()){Edgeedge=adj[v].dequeue();if(edge.isUsed)continue;edge.isUsed=true;stack.push(v);v=edge.other(v);}// push vertex with no more leaving edges to cyclecycle.push(v);}// check if all edges are usedif(cycle.size()!=G.E()+1)cycle=null;}// returns the sequence of vertices on an Eulerian cyclepublicIterable<Integer>cycle(){returncycle;}// returns true if the graph has an Eulerian cyclepublicbooleanhasEulerianCycle(){returncycle!=null;}// returns any non-isolated vertex; -1 if no such vertexprivatestaticintnonIsolatedVertex(GraphG){for(intv=0;v<G.V();v++)if(G.degree(v)>0)returnv;return-1;}}
packageedu.princeton.cs.algs4;publicclassTopological{privateIterable<Integer>order;// topological orderprivateint[]rank;// rank[v] = rank of vertex v in order// determines whether the digraph {@code G} has a topological order and,// if so, finds such a topological order.publicTopological(DigraphG){DirectedCyclefinder=newDirectedCycle(G);if(!finder.hasCycle()){DepthFirstOrderdfs=newDepthFirstOrder(G);order=dfs.reversePost();rank=newint[G.V()];inti=0;for(intv:order)rank[v]=i++;}}// returns a topological order if the digraph has a topological order,// and {@code null} otherwise.publicIterable<Integer>order(){returnorder;}// does the digraph have a topological order?publicbooleanhasOrder(){returnorder!=null;}// the rank of vertex {@code v} in the topological order;// -1 if the digraph is not a DAGpublicintrank(intv){if(hasOrder())returnrank[v];elsereturn-1;}/*************************************************************************** * actually {@code DirectedCycle} is a class in edu.princeton.cs.algs4 * here modifies and includes it as follows, just for learning ***************************************************************************/privateclassDirectedCycle{privateboolean[]marked;privateint[]edgeTo;privateboolean[]onStack;privateStack<Integer>cycle;publicDirectedCycle(DigraphG){marked=newboolean[G.V()];onStack=newboolean[G.V()];edgeTo=newint[G.V()];for(intv=0;v<G.V();v++)if(!marked[v]&&cycle==null)dfs(G,v);}privatevoiddfs(DigraphG,intv){onStack[v]=true;marked[v]=true;for(intw:G.adj(v)){if(cycle!=null)return;elseif(!marked[w]){edgeTo[w]=v;dfs(G,w);}// trace back directed cycleelseif(onStack[w]){cycle=newStack<Integer>();for(intx=v;x!=w;x=edgeTo[x]){cycle.push(x);}cycle.push(w);cycle.push(v);}}onStack[v]=false;}publicbooleanhasCycle(){returncycle!=null;}}/*************************************************************************** * actually {@code DepthFirstOrder} is a class in edu.princeton.cs.algs4 * here modifies and includes it as follows, just for learning ***************************************************************************/privateclassDepthFirstOrder{privateboolean[]marked;privateStack<Integer>reversePost;publicDepthFirstOrder(DigraphG){reversePost=newStack<Integer>();marked=newboolean[G.V()];for(intv=0;v<G.V();v++)if(!marked[v])dfs(G,v);}privatevoiddfs(DigraphG,intv){marked[v]=true;for(intw:G.adj(v))if(!marked[w])dfs(G,w);reversePost.push(v);}publicIterable<Integer>reversePost(){returnreversePost;}}}
packageedu.princeton.cs.algs4;publicclassKosarajuSharirSCC{privateboolean[]marked;// marked[v] = has vertex v been visited?privateint[]id;// id[v] = id of strong component containing vprivateintcount;// number of strongly-connected componentspublicKosarajuSharirSCC(DigraphG){// compute reverse postorder of reverse graphDepthFirstOrderdfs=newDepthFirstOrder(G.reverse());// run DFS on G, using reverse postorder to guide calculationmarked=newboolean[G.V()];id=newint[G.V()];for(intv:dfs.reversePost()){if(!marked[v]){dfs(G,v);count++;}}}// DFS on graph Gprivatevoiddfs(DigraphG,intv){marked[v]=true;id[v]=count;for(intw:G.adj(v)){if(!marked[w])dfs(G,w);}}publicintid(intv){returnid[v];}publicintcount(){returncount;}// are the two vertices strongly connected?publicbooleanstronglyConnected(intv,intw){validateVertex(v);validateVertex(w);returnid[v]==id[w];}/*************************************************************************** * actually {@code DepthFirstOrder} is a class in edu.princeton.cs.algs4 * here modifies and includes it as follows, just for learning ***************************************************************************/privateclassDepthFirstOrder{privateboolean[]marked;privateStack<Integer>reversePost;privateDepthFirstOrder(DigraphG){reversePost=newStack<Integer>();marked=newboolean[G.V()];for(intv=0;v<G.V();v++)if(!marked[v])dfs(G,v);}privatevoiddfs(DigraphG,intv){marked[v]=true;for(intw:G.adj(v))if(!marked[w])dfs(G,w);reversePost.push(v);}privateIterable<Integer>reversePost(){returnreversePost;}}}
packageedu.princeton.cs.algs4;publicclassKruskalMST{privatedoubleweight;// weight of MSTprivateQueue<Edge>mst=newQueue<Edge>();// edges in MST// compute a minimum spanning tree (or forest) of an edge-weighted graph.publicKruskalMST(EdgeWeightedGraphG){// build priority queueMinPQ<Edge>pq=newMinPQ<Edge>();for(Edgee:G.edges())pq.insert(e);// run greedy algorithmUFuf=newUF(G.V());while(!pq.isEmpty()&&mst.size()<G.V()-1){Edgee=delMin();intv=e.either();intw=e.other(v);// v-w does not create a cycleif(uf.find(v)!=uf.find(w)){uf.union(v,w);// merge v and w componentsmst.enqueue(e);// add edge e to mstweight+=e.weight();}}}publicIterable<Edge>edges(){returnmst;}publicdoubleweight(){returnweight;}}
packageedu.princeton.cs.algs4;publicclassLazyPrimMST{privatedoubleweight;// total weight of MSTprivateQueue<Edge>mst;// edges in the MSTprivateboolean[]marked;// marked[v] = true iff v on treeprivateMinPQ<Edge>pq;// edges with one endpoint in tree// compute a minimum spanning tree (or forest) of an edge-weighted graph.publicLazyPrimMST(EdgeWeightedGraphG){mst=newQueue<Edge>();pq=newMinPQ<Edge>();marked=newboolean[G.V()];for(intv=0;v<G.V();v++)// run Prim from all vertices toif(!marked[v])prim(G,v);// get a minimum spanning forest}// run Prim's algorithmprivatevoidprim(EdgeWeightedGraphG,ints){scan(G,s);while(!pq.isEmpty()){// better to stop when mst has V-1 edgesEdgee=pq.delMin();intv=e.either(),w=e.other(v);if(marked[v]&&marked[w])continue;// lazy, both v and w already scannedmst.enqueue(e);// add e to MSTweight+=e.weight();if(!marked[v])scan(G,v);if(!marked[w])scan(G,w);}}// add all edges e incident to v onto pq if the other endpoint has not yet been scannedprivatevoidscan(EdgeWeightedGraphG,intv){marked[v]=true;for(Edgee:G.adj(v))if(!marked[e.other(v)])pq.insert(e);}publicIterable<Edge>edges(){returnmst;}publicdoubleweight(){returnweight;}}
packageedu.princeton.cs.algs4;publicclassPrimMST{privateEdge[]edgeTo;// edgeTo[v] = shortest edge from tree vertex to non-tree vertexprivatedouble[]distTo;// distTo[v] = weight of shortest such edgeprivateboolean[]marked;// marked[v] = true if v on tree, false otherwiseprivateIndexMinPQ<Double>pq;// compute a minimum spanning tree (or forest) of an edge-weighted graph.publicPrimMST(EdgeWeightedGraphG){edgeTo=newEdge[G.V()];distTo=newdouble[G.V()];marked=newboolean[G.V()];pq=newIndexMinPQ<Double>(G.V());for(intv=0;v<G.V();v++)distTo[v]=Double.POSITIVE_INFINITY;for(intv=0;v<G.V();v++)// run from each vertex to findif(!marked[v])prim(G,v);// minimum spanning forest}// run Prim's algorithm in graph G, starting from vertex sprivatevoidprim(EdgeWeightedGraphG,ints){distTo[s]=0.0;pq.insert(s,distTo[s]);while(!pq.isEmpty()){intv=pq.delMin();scan(G,v);}}// scan vertex vprivatevoidscan(EdgeWeightedGraphG,intv){marked[v]=true;for(Edgee:G.adj(v)){intw=e.other(v);if(marked[w])continue;// v-w is obsolete edgeif(e.weight()<distTo[w]){distTo[w]=e.weight();edgeTo[w]=e;if(pq.contains(w))pq.decreaseKey(w,distTo[w]);elsepq.insert(w,distTo[w]);}}}publicIterable<Edge>edges(){Queue<Edge>mst=newQueue<Edge>();for(intv=0;v<edgeTo.length;v++){Edgee=edgeTo[v];if(e!=null){mst.enqueue(e);}}returnmst;}publicdoubleweight(){doubleweight=0.0;for(Edgee:edges())weight+=e.weight();returnweight;}}