Q:

Remove duplicates items in list using the GLib collections

I have app that can scan freq from v4l2 device and manage them.
For this have two function:
Function to scan and append found freq to GList * stations: 
typedef struct {
    GList *stations;
} FreqScanData;

gboolean scan_cb (gpointer data)
{
    static gfloat  freq = FREQ_MIN - 4.0f/STEPS;
    FreqScanData  *fsd = data;

g_assert (fsd);

    if (check_station (freq)) {
        gfloat *f;

        f = g_malloc (sizeof (gfloat));

        *f = freq;
        fsd->stations = g_list_append (fsd->stations, f);
    }

    freq += 1.0/STEPS;

    return TRUE;
}

Function to append freq from GList * stations to existing list GList * presets:
typedef struct {
{
    GList *presets;
} Settings;

typedef struct Preset preset;
struct Preset
{
    gchar *name;
    gfloat freq;
};

void scan (void)
{
    FreqScanData data;
    Settings settings;
    GList *node;

    for (node = data.stations; node; node = node->next) {
        preset *ps;

        ps = g_malloc0 (sizeof (preset));
        ps->name = g_strdup (_("unnamed"));
        ps->freq = * ((gfloat *) node->data);                       

        settings.presets = g_list_append (settings.presets, ps);
        g_free (node->data);
    }
}

I want help with this case:
If freq found and appended in data.stations list are already in settings.presets list, then do not append them again.
For example:
scan stations list found:
87.50
92.20
101.50
104.50
106.60

and presets list have these items:
101.50
92.20

-> do not duplicate them in result list

A:

As Philip mentioned, it would probably be better to use a hash table (or a tree) instead.  That said, that wasn't your question (which, I assume, is why he suggested it in a comment not an answer).
If you want to keep using a linked list, there are really only two options: do a full scan every time you want to insert data, or keep the data sorted and a full scan becomes your worst case, but on average you only have to scan half the list.
You're actually doing a full scan already since you're using g_list_append instead of g_list_prepend.  All you would have to do to eliminate duplicates is traverse the list yourself until you reach the end, checking each value to see if the frequency is equal to the one you're inserting and, if so, abort the insert.  However, it would probably be better to keep the presets sorted, so...
If you keep the list sorted by frequency you just have to traverse the list, checking each value to see if the frequency of each item is equal to the one you're inserting.  If so, abort the insert.  If not and the frequency of the existing item is greater than the value you're trying to insert, insert the value before the current item.  If the frequency is less than the value you're trying to insert, continue to the next item.  It would look something like this:
static void preset_free (preset* ps)
{
  g_free (ps->name);
  g_free (ps);
}

static int preset_compare (preset* a, preset* b) {
  if (a->freq < b->freq)
    return -1;
  else if (a->freq > b->freq)
    return 1;
  else
    return 0;
}

static GList* insert_or_ignore_sorted (GList* list, preset* ps, GCompareFunc func) {
  GList* cur = list;
  int cmp_res;

  for (; cur != NULL ; cur = cur->next) {
    cmp_res = preset_compare ((preset*) cur->data, ps);
    if (cmp_res == 0) {
      preset_free (ps);
      return;
    }
    if (cmp_res > 0)
      break;
  }

  return g_list_insert_before (list, cur, ps);
}

void scan (FreqScanData* data)
{
  Settings settings = { NULL };
  GList *node;

  for (node = data->stations; node; node = node->next) {
    preset *ps;

    ps = g_malloc0 (sizeof (preset));
    ps->name = g_strdup (_("unnamed"));
    ps->freq = * ((gfloat *) node->data);

    settings.presets = insert_or_ignore_sorted (settings.presets, ps, (GCompareFunc) preset_compare);
    g_free (node->data);
  }
}

