単連結リストの整列 #25 名前とスコアが要素のリストを使ってみる

サンプルコードを書いてsclistを使ってみる。

test_sclist.c
#include <stdio.h>
#include <string.h>
#include "sclist.h"

#define UNUSED_ARG(x) (void)(x)

static sclist_t make(void)
{
    struct { char *n; int s; } *p, d[] = {
        {"Amelia", 6}, {"Barbara", 4}, {"Charlotte", 5},
        {"Caroline", 7}, {"Brianna", 3}, {"Agatha", 6},
        {NULL, 0}
    };
    sclist_t x = sclist_new();
    for (p = d; p->n != NULL; p++) sclist_add(x, p->n, p->s);
    return x;
}

static void print(sclist_t list)
{
    sciter_t i = sclist_iterator(list);
    if (sciter_has_next(i)) {
        for (;;) {
            scdata_t d = sciter_next(i);
            printf("%s=%d", scdata_get_name(d), scdata_get_score(d));
            if (! sciter_has_next(i)) break;
            fputs(", ", stdout);
        }
    }
    putchar('\n');
}

static int order(const scdata_t x, const scdata_t y, void *arg)
{
    int xs = scdata_get_score(x), ys = scdata_get_score(y);
    UNUSED_ARG(arg);
    return xs == ys ? strcmp(scdata_get_name(x), scdata_get_name(y)) > 0 : xs > ys;
}

int main(void)
{
    sclist_t list = make();
    print(list);
    sclist_sort(list, order, NULL);
    print(list);
    sclist_add(list, "Dorothy", 2);
    print(list);
    sclist_sort(list, order, NULL);
    print(list);
    sclist_dispose(list);
    return 0;
}

関数makeは初期データ入りのリストを作る。
関数printはリストの内容を表示する。
関数orderは順序定義関数であり、
スコアの大きいものが上位、同じスコアなら名前を構成する文字コードの大きさで順位が決まる。
プログラム全体は初期リスト作成→整列→データ追加→整列→リストの廃棄の順で処理している。
実行すると、

$ ./test_sclist
Amelia=6, Barbara=4, Charlotte=5, Caroline=7, Brianna=3, Agatha=6
Brianna=3, Barbara=4, Charlotte=5, Agatha=6, Amelia=6, Caroline=7
Brianna=3, Barbara=4, Charlotte=5, Agatha=6, Amelia=6, Caroline=7, Dorothy=2
Dorothy=2, Brianna=3, Barbara=4, Charlotte=5, Agatha=6, Amelia=6, Caroline=7

とりあえず期待通りにスコアの昇順に整列した。