Esempio n. 1
0
void
list_merge (list_t * dest, list_t * sour, int compare (const void *, const void *))
{
	lnode_t *dn, *sn, *tn;
	lnode_t *d_nil = list_nil (dest), *s_nil = list_nil (sour);

	/* Nothing to do if source and destination list are the same. */
	if (dest == sour)
		return;

	/* overflow check */
	nassert (list_count (sour) + list_count (dest) >= list_count (sour));

	/* lists must be sorted */
	nassert (list_is_sorted (sour, compare));
	nassert (list_is_sorted (dest, compare));

	dn = list_first_priv (dest);
	sn = list_first_priv (sour);

	while (dn != d_nil && sn != s_nil) {
		if (compare (lnode_get (dn), lnode_get (sn)) >= 0) {
			tn = lnode_next (sn);
			list_delete (sour, sn);
			list_ins_before (dest, sn, dn);
			sn = tn;
		} else {
			dn = lnode_next (dn);
		}
	}

	if (dn != d_nil)
		return;

	if (sn != s_nil)
		list_transfer (dest, sour, sn);
}
Esempio n. 2
0
void list_sort(list_t *list, int compare(const void *, const void *))
{
    list_t extra;
    listcount_t middle;
    lnode_t *node;

    if (list_count(list) > 1) {
        middle = list_count(list) / 2;
        node = list_first_priv(list);

        list_init(&extra, list_count(list) - middle);

        while (middle--)
            node = lnode_next(node);

        list_transfer(&extra, list, node);
        list_sort(list, compare);
        list_sort(&extra, compare);
        list_merge(list, &extra, compare);
    }
    assert (list_is_sorted(list, compare));
}