zoukankan      html  css  js  c++  java
  • glib 树

    原文地址: http://hi.baidu.com/study_together/blog/item/0ffc733c224211cf7c1e7138.html

    编译:gcc -g -Wall -O0 fuck.c -o fuck `pkg-config --libs --cflags glib-2.0`

    1

    树的基本操作

    这里是在树中可以执行的一些基本操作:

    #include <glib.h>
    #include
    <stdio.h>

    int main(int argc, char** argv) {
    GTree
    * t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
    g_tree_insert(t,
    "c", "Chicago");
    printf(
    "The tree height is %d because there's only one node\n", g_tree_height(t));
    g_tree_insert(t,
    "b", "Boston");
    g_tree_insert(t,
    "d", "Detroit");
    printf(
    "Height is %d since c is root; b and d are children\n", g_tree_height(t));
    printf(
    "There are %d nodes in the tree\n", g_tree_nnodes(t));
    g_tree_remove(t,
    "d");
    printf(
    "After remove(), there are %d nodes in the tree\n", g_tree_nnodes(t));
    g_tree_destroy(t);
    return 0;
    }

    ***** Output *****

    The tree height is 1 because there's only one node
    Height is 2 since c is root; b and d are children
    There are 3 nodes in the tree
    After remove(), there are 2 nodes in the tree

    2

    替换和提取

    在前面的 GHashTable 部分已经看到了 replace 和 steal 函数名, 关于 GTree 的函数也是如此。

    g_tree_replace 会同时替换一个 GTree 条目的键和值,不同于 g_tree_insert,如果要插入的键是重复的,则它只是将值替换。

    不需要调用任何 GDestroyNotify 函数,g_tree_steal 就可以删除一个节点。 这里是一个示例:

    #include <glib.h>
    #include
    <stdio.h>

    void key_d(gpointer data) {
    printf(
    "Key %s destroyed\n", data);
    }
    void value_d(gpointer data) {
    printf(
    "Value %s destroyed\n", data);
    }
    int main(int argc, char** argv) {
    GTree
    * t = g_tree_new_full((GCompareDataFunc)g_ascii_strcasecmp,
    NULL, (GDestroyNotify)key_d, (GDestroyNotify)value_d);
    g_tree_insert(t,
    "c", "Chicago");
    g_tree_insert(t,
    "b", "Boston");
    g_tree_insert(t,
    "d", "Detroit");
    printf(
    ">Replacing 'b', should get destroy callbacks\n");
    g_tree_replace(t,
    "b", "Billings");
    printf(
    ">Stealing 'b', no destroy notifications will occur\n");
    g_tree_steal(t,
    "b");
    printf(
    ">Destroying entire tree now\n");
    g_tree_destroy(t);
    return 0;
    }

    ***** Output *****

    >Replacing 'b', should get destroy callbacks
    Value Boston destroyed
    Key b destroyed
    >Stealing 'b', no destroy notifications will occur
    >Destroying entire tree now
    Key d destroyed
    Value Detroit destroyed
    Key c destroyed
    Value Chicago destroyed

    3

    查找数据

    GTree 具备只查找键或者同时查找键和值的方法。这与在 GHashTable 部分中接触到的非常类似;

    有一个 lookup 以及一个 lookup_extended。这里是一个示例:

    #include <glib.h>
    #include
    <stdio.h>

    int main(int argc, char** argv) {
    GTree
    * t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
    g_tree_insert(t,
    "c", "Chicago");
    g_tree_insert(t,
    "b", "Boston");
    g_tree_insert(t,
    "d", "Detroit");
    printf(
    "The data at 'b' is %s\n", g_tree_lookup(t, "b"));
    printf(
    "%s\n", g_tree_lookup(t, "a") ? "My goodness!" : "As expected, couldn't find 'a'");

    gpointer
    * key = NULL;
    gpointer
    * value = NULL;
    g_tree_lookup_extended(t,
    "c", (gpointer*)&key, (gpointer*)&value);
    printf(
    "The data at '%s' is %s\n", key, value);
    gboolean found
    = g_tree_lookup_extended(t, "a", (gpointer*)&key, (gpointer*)&value);
    printf(
    "%s\n", found ? "My goodness!" : "As expected, couldn't find 'a'");

    g_tree_destroy(t);
    return 0;
    }

    ***** Output *****

    The data at 'b' is Boston
    As expected, couldn't find 'a'
    The data at 'c' is Chicago
    As expected, couldn't find 'a'


    4

    使用 foreach 列出树

    GTree 提供了一个 g_tree_foreach 函数,用来以有序的顺序遍历整棵对。这里是一个示例:

    #include <glib.h>
    #include
    <stdio.h>

    gboolean iter_all(gpointer key, gpointer value, gpointer data) {
    printf(
    "%s, %s\n", key, value);
    return FALSE;
    }
    gboolean iter_some(gpointer key, gpointer value, gpointer data) {
    printf(
    "%s, %s\n", key, value);
    return g_ascii_strcasecmp(key, "b") == 0;
    }
    int main(int argc, char** argv) {
    GTree
    * t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
    g_tree_insert(t,
    "d", "Detroit");
    g_tree_insert(t,
    "a", "Atlanta");
    g_tree_insert(t,
    "c", "Chicago");
    g_tree_insert(t,
    "b", "Boston");
    printf(
    "Iterating all nodes\n");
    g_tree_foreach(t, (GTraverseFunc)iter_all, NULL);
    printf(
    "Iterating some of the nodes\n");
    g_tree_foreach(t, (GTraverseFunc)iter_some, NULL);
    g_tree_destroy(t);
    return 0;
    }

    ***** Output *****

    Iterating all nodes
    a, Atlanta
    b, Boston
    c, Chicago
    d, Detroit
    Iterating some of the nodes
    a, Atlanta
    b, Boston

    5

    搜索

    可以使用 g_tree_foreach 搜索条目,如果知道键,可以使用 g_tree_lookup。 不过,要进行更复杂地搜索,可以使用 g_tree_search 函数。

    这里是其工作方式:

    #include <glib.h>
    #include
    <stdio.h>

    gint finder(gpointer key, gpointer user_data) {
    int len = strlen((char*)key);
    if (len == 3) {
    return 0;
    }
    return (len < 3) ? 1 : -1;
    }
    int main(int argc, char** argv) {
    GTree
    * t = g_tree_new((GCompareFunc)g_ascii_strcasecmp);
    g_tree_insert(t,
    "dddd", "Detroit");
    g_tree_insert(t,
    "a", "Annandale");
    g_tree_insert(t,
    "ccc", "Cleveland");
    g_tree_insert(t,
    "bb", "Boston");
    gpointer value
    = g_tree_search(t, (GCompareFunc)finder, NULL);
    printf(
    "Located value %s; its key is 3 characters long\n", value);
    g_tree_destroy(t);
    return 0;
    }

    ***** Output *****

    Located value Cleveland; its key is 3 characters long

    6

    不只是二叉:n-叉 树

    GLib n-叉 树实现基于 GNode 数据结构;以前所述,它允许每个父节点有多个子节点。 好像很少会用到它,不过,完整起见,这里给出一个用法示例:

    #include <glib.h>
    #include
    <stdio.h>

    gboolean iter(GNode
    * n, gpointer data) {
    printf(
    "%s ", n->data);
    return FALSE;
    }
    int main(int argc, char** argv) {
    GNode
    * root = g_node_new("Atlanta");
    g_node_append(root, g_node_new(
    "Detroit"));
    GNode
    * portland = g_node_prepend(root, g_node_new("Portland"));
    printf(
    ">Some cities to start with\n");
    g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
    -1, iter, NULL);
    printf(
    "\n>Inserting Coos Bay before Portland\n");
    g_node_insert_data_before(root, portland,
    "Coos Bay");
    g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
    -1, iter, NULL);
    printf(
    "\n>Reversing the child nodes\n");
    g_node_reverse_children(root);
    g_node_traverse(root, G_PRE_ORDER, G_TRAVERSE_ALL,
    -1, iter, NULL);
    printf(
    "\n>Root node is %s\n", g_node_get_root(portland)->data);
    printf(
    ">Portland node index is %d\n", g_node_child_index(root, "Portland"));
    g_node_destroy(root);
    return 0;
    }

    ***** Output *****

    >Some cities to start with
    Atlanta Portland Detroit
    >Inserting Coos Bay before Portland
    Atlanta Coos Bay Portland Detroit
    >Reversing the child nodes
    Atlanta Detroit Portland Coos Bay
    >Root node is Atlanta
    >Portland node index is 1

  • 相关阅读:
    iOS 的 Block 的使用
    iOS 的Could not find Developer Disk Image错误
    iOS 面试
    iOS 开发工具——统计Crash的工具Crashlytics
    iOS 的 Foundation 框架
    iOS 页面之间的传值总结
    iOS 常用四种数据存储方式
    iOS 的 Delegate Notification KVO
    iOS 的 Delegate 设计模式 及 自定义代理
    iOS 的 NSNumber(对基本数据类型) & NSValue(对结构体) 的装箱
  • 原文地址:https://www.cnblogs.com/wangkangluo1/p/2101998.html
Copyright © 2011-2022 走看看