/* * Sort (part of) a list. * Input: * - list: The list to be sorted; list cannot be NULL. * - limit: Recursion limit. * Output: * - head_out: The head of the sorted list containing the first 2^(level+1) elements of the * input list; if the input list has fewer elements, head_out be a sorted list * containing all the elements of the input list. * Returns the head of the list of unprocessed elements (NULL if the sorted list contains * all the elements of the input list). * * Implementation notes: * Special case single element list, unroll/inline the sorting of the first two elements. * Some tail recursion is used since we iterate on the bottom-up solution of the problem * (we start with a small sorted list and keep merging other lists of the same size to it). */ static edge_t * sort_edges (edge_t *list, unsigned int level, edge_t **head_out) { edge_t *head_other, *remaining; unsigned int i; head_other = list->next; if (head_other == NULL) { *head_out = list; return NULL; } remaining = head_other->next; if (list->x <= head_other->x) { *head_out = list; head_other->next = NULL; } else { *head_out = head_other; head_other->prev = list->prev; head_other->next = list; list->prev = head_other; list->next = NULL; } for (i = 0; i < level && remaining; i++) { remaining = sort_edges (remaining, i, &head_other); *head_out = merge_sorted_edges (*head_out, head_other); } return remaining; }
Edges Graph::find_min_span() { Edges min_span; sort_edges(); for (int i = 0; i < edges.size(); i++) { int f = edges[i].f; int t = edges[i].t; if (!joined(f, t)) { join(f, t); min_span.push_back(edges[i]); if (sets[f].size() == num_vert) break; } } return min_span; }
static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect, SkBlitter* blitter, const SkIRect& ir) { SkASSERT(pts && blitter); SkEdge edgeStorage[3]; SkEdge* list[3]; int count = build_tri_edges(edgeStorage, pts, clipRect, list); if (count < 2) { return; } SkEdge headEdge, tailEdge, *last; // this returns the first and last edge after they're sorted into a dlink list SkEdge* edge = sort_edges(list, count, &last); headEdge.fPrev = nullptr; headEdge.fNext = edge; headEdge.fFirstY = kEDGE_HEAD_Y; headEdge.fX = SK_MinS32; edge->fPrev = &headEdge; tailEdge.fPrev = last; tailEdge.fNext = nullptr; tailEdge.fFirstY = kEDGE_TAIL_Y; last->fNext = &tailEdge; // now edge is the head of the sorted linklist int stop_y = ir.fBottom; if (clipRect && stop_y > clipRect->fBottom) { stop_y = clipRect->fBottom; } int start_y = ir.fTop; if (clipRect && start_y < clipRect->fTop) { start_y = clipRect->fTop; } walk_simple_edges(&headEdge, blitter, start_y, stop_y); }
void Kruskal(LGraph G) { int p1, p2; int m, n; int index = 0; int vends[MAXN] = {0}; //用于保存"已有最小生成树"中每个顶点在该最小树中的终点。 //for ex:已经有一条边AB了,那么vends[A.pos] = B.pos EData rets[MAXN]; //结果数组,保存生成树的边 EData *edges; //图对应的所有边 edges = get_edges(G); sort_edges(edges, G.edgnum); for (int i = 0; i < G.edgnum; ++i) { p1 = getPos(G, edges[i].start); p2 = getPos(G, edges[i].end); m = get_end(vends, p1); n = get_end(vends, p2); //m != n说明没有形成环 if (m != n) { vends[m] = n; rets[index++] = edges[i]; } } free(edges); int length = 0; for (int i = 0; i < index; ++i) length += rets[i].weight; printf("Kruskal = %d: ", length); for (int i = 0; i < index; ++i) printf("(%c, %c) ", rets[i].start, rets[i].end); printf("\n"); }
/*Arvore Geradora Mínima através do algoritmo de Kruskal.*/ void AGM_Kruskal (Graph *G) { /*Arestas da árvore geradora mínima: */ Edge MST[G->V]; /*Para cada v em G->V crie um conjunto: */ Set *sets = Make_sets (G->V); Edge *E = sort_edges (G); int uv, i; int e = 0; /*Para cada aresta {u,v} do Grafo: */ for (uv = 0; uv < G->E-1; uv++) { /*Retire a aresta com menor peso: */ Edge min = E[uv]; /*Verifique quem são as raizes: */ int u = Find (sets, min.u); int v = Find (sets, min.v); /*Se a inclusão da aresta não cria um ciclo, então a adicione:*/ if (u != v) { MST[e++] = min; Union (sets, u, v); } } printf("\n\nÁrvore geradora mínima por Kruskal: \n"); for (i = 0; i < e; i++) { printf("Aresta: %d - %d com peso %d.\n", MST[i].u, MST[i].v, MST[i].weight); } free(E); }
// clipRect has not been shifted up void sk_fill_path(const SkPath& path, const SkIRect& clipRect, SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip) { SkASSERT(blitter); SkIRect shiftedClip = clipRect; shiftedClip.fLeft = SkLeftShift(shiftedClip.fLeft, shiftEdgesUp); shiftedClip.fRight = SkLeftShift(shiftedClip.fRight, shiftEdgesUp); shiftedClip.fTop = SkLeftShift(shiftedClip.fTop, shiftEdgesUp); shiftedClip.fBottom = SkLeftShift(shiftedClip.fBottom, shiftEdgesUp); SkEdgeBuilder builder; int count = builder.build_edges(path, &shiftedClip, shiftEdgesUp, pathContainedInClip); SkEdge** list = builder.edgeList(); if (0 == count) { if (path.isInverseFillType()) { /* * Since we are in inverse-fill, our caller has already drawn above * our top (start_y) and will draw below our bottom (stop_y). Thus * we need to restrict our drawing to the intersection of the clip * and those two limits. */ SkIRect rect = clipRect; if (rect.fTop < start_y) { rect.fTop = start_y; } if (rect.fBottom > stop_y) { rect.fBottom = stop_y; } if (!rect.isEmpty()) { blitter->blitRect(rect.fLeft << shiftEdgesUp, rect.fTop << shiftEdgesUp, rect.width() << shiftEdgesUp, rect.height() << shiftEdgesUp); } } return; } SkEdge headEdge, tailEdge, *last; // this returns the first and last edge after they're sorted into a dlink list SkEdge* edge = sort_edges(list, count, &last); headEdge.fPrev = nullptr; headEdge.fNext = edge; headEdge.fFirstY = kEDGE_HEAD_Y; headEdge.fX = SK_MinS32; edge->fPrev = &headEdge; tailEdge.fPrev = last; tailEdge.fNext = nullptr; tailEdge.fFirstY = kEDGE_TAIL_Y; last->fNext = &tailEdge; // now edge is the head of the sorted linklist start_y = SkLeftShift(start_y, shiftEdgesUp); stop_y = SkLeftShift(stop_y, shiftEdgesUp); if (!pathContainedInClip && start_y < shiftedClip.fTop) { start_y = shiftedClip.fTop; } if (!pathContainedInClip && stop_y > shiftedClip.fBottom) { stop_y = shiftedClip.fBottom; } InverseBlitter ib; PrePostProc proc = nullptr; if (path.isInverseFillType()) { ib.setBlitter(blitter, clipRect, shiftEdgesUp); blitter = &ib; proc = PrePostInverseBlitterProc; } // count >= 2 is required as the convex walker does not handle missing right edges if (path.isConvex() && (nullptr == proc) && count >= 2) { walk_simple_edges(&headEdge, blitter, start_y, stop_y); } else { walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc, shiftedClip.right()); } }
static edge_t * merge_unsorted_edges (edge_t *head, edge_t *unsorted) { sort_edges (unsorted, UINT_MAX, &unsorted); return merge_sorted_edges (head, unsorted); }