/*
 * 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;
}
Beispiel #3
0
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");
	
}
Beispiel #5
0
/*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);
}
Beispiel #6
0
// 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);
}