Dijkstra, PQ as hash with chaining (or buckets over distances, if you prefer). Graph is passed as a forward star, arrays index for vertices, jver for nodes, dist for distances. Comments in italian, sorry. // ---------------------------------------------------------------------- // space required in bytes: 4*narc + 12*nver + 2*maxd int DikstraSingleHash( int root, // la sorgente int sink, // la destinazione, se c'e', altrimenti -1 int nver, // numero di vertici int narc, // numero di archi int maxd, // massima lunghezza di un arco (serve per l'hashing) + 1 ref int nperm, // numero nodi diventati permanenti int[] index, // array indice dei nodi int[] dist, // le distanze dalla sorgente int[] ipred, // i predecessori int[] jver, // array degli archi, endnode int[] darc) // lunghezze degli archi { int ct,pt,v,qq,i,k, large, inew, nvuoti, ipos1, ipos2, jj, jjdist, lx, ls, ll, ipt; int[] next = new int[nver]; // interno, gestione sottoliste chaining int[] last = new int[nver]; // interno, gestione sottoliste chaining int[] head = new int[maxd+1]; // interno, gestione hash int[] tail = new int[maxd+1]; // interno, gestione hash //StreamWriter dlog = new StreamWriter("dijkstra.log"); large = 1000000000; for(k=0;k<=maxd;k++) { head[k] = 0; tail[k] = 0; } for(i=0;i=jjdist) continue; // goto next k //dlog.WriteLine("relabelling jj={0,5} former length {1,7} new {2,7}",jj,jjdist,v); // jj needs relabeling (new shortest path to jj of length jjdist) if(jjdist==large) goto lab150; // jj was already labelled and must therefore be in some sublist qq = (jjdist % maxd); // jj was in the sublist of qq. now remove it. lx = next[jj]; ls = last[jj]; if(lx==0) { if(ls==0) { //jj in the top = bottom head[qq] = 0; tail[qq] = 0; } else { //jj in the bottom tail[qq] = ls; next[ls] = 0; } } else { if(ls==0) { //jj in the top head[qq] = lx; last[lx] = 0; } else { //jj in the middle of the list last[lx] = ls; next[ls] = lx; } } // jj removed from sublist qq. now put jj into its new sublist lab150: qq = (v % maxd); //dlog.WriteLine("New hash of jj: qq="+qq); if(head[qq]==0) { //the sublist qq is empty head[qq]=jj; last[jj]=0; } else { //some vertex is already in sublist qq ll = tail[qq]; last[jj]=ll; next[ll]=jj; } ipred[jj] = inew; dist[jj] = v; tail[qq] = jj; next[jj] = 0; } // for k // finishes for k when inew has been scanned // now select new vertex to make label permanent if(next[inew]>0) { inew = next[inew]; //dlog.WriteLine("Expanding from inew list. next inew="+inew); goto lab100; } // sublist pt containing inew is empty // try first vertex in next non empty sublist head[pt]=0; for(ct=0;ct<=maxd;ct++) { ipt = pt+1; pt = (ipt % maxd); if(head[pt]>0) { // ll = head(pt) // last(ll) = inew // next(inew)= ll // inew = ll inew = head[pt]; //dlog.WriteLine("Expanding from pt ({0,4}) list. next inew={1}",pt,inew); goto lab100; } else nvuoti = nvuoti + 1; // conto quante volte ho provato a espandere celle vuote } // finishes when no more non empty lists can be found. // the unlabelled vertices can not be reached lab500: //dlog.WriteLine(" nvuoti {0}",nvuoti); //dlog.Close(); return(0); } }