कैसे कुशलतापूर्वक पिछले कुंजी और GTree में मूल्य खोजने के लिए

वोट
0

मैं कार्यों का विस्तार करने का एक सेट विकसित करने की आवश्यकता glib2 GTreeके साथ:

  • पहला तत्व को खोजने
  • पिछले लगता है
  • निकटतम लगता है (मंजिल, प्लस्तर लगाना, सबसे बड़ी कम, की तुलना में कम से कम से अधिक)

पहले ढूँढना आसान है। आप बस को रोकने के g_tree_foreach()लिए पहले के बाद calback। लेकिन यह कैसे पिछले तत्व को खोजने के लिए पूरे वृक्ष traversing के बिना ?

मुझे लगता है मैं इस्तेमाल कर सकते हैं सोचा g_tree_search()एक कॉलबैक कि पाया जब तक एक सकारात्मक मूल्य लौटने रहता है के साथ है, लेकिन मैं कैसे जानते हो मैं पिछले तत्व पर वर्तमान में कर रहा हूँ?

#include <stdio.h>
#include <sys/types.h>
#include <string.h>

#include <glib.h>

static
gint compare_int(gconstpointer p1, gconstpointer p2) {
    int i1 = GPOINTER_TO_INT(p1);
    int i2 = GPOINTER_TO_INT(p2);
    //printf(%d %d\n, i1, i2);
    return i1 == i2 ? 0 : i1 > i2 ? 1 : -1;
}


static
gboolean traverse(gpointer key, gpointer value, gpointer data) {
    //int ikey = GPOINTER_TO_INT(key);
    const char *sval = (const char *)value;
    printf(%s\n, sval);
    return FALSE;
}

static
gint find_last(gconstpointer p, gpointer user_data) {
    return 1;
}

static inline const char *NULS(const char *s) {
    return s ? s : NULL;
}

int main(int argc, char *argv[]) {
    GTree *tree = g_tree_new(compare_int);
    g_tree_insert(tree, GINT_TO_POINTER(10), ten);
    g_tree_insert(tree, GINT_TO_POINTER(-99), minus ninety-nine);
    g_tree_insert(tree, GINT_TO_POINTER(8), eight);
    g_tree_foreach(tree, traverse, NULL);
    printf(=======\n%s\n, NULS((const char*)g_tree_search(tree, (GCompareFunc)find_last, NULL)));
    return 0;
}
03/06/2017 को 21:33
का स्रोत उपयोगकर्ता
अन्य भाषाओं में...                            


1 जवाब

वोट
0

मैं पूरी तरह से अपने खुद के पेड़ को लागू नहीं करना चाहता क्योंकि मैं पर उन्नत खोज प्रदर्शन करने के लिए करना चाहता था था GTree3 पक्ष के कोड से प्राप्त उदाहरणों।

इसके बजाय मैंने सोचा था कि GLib लेखकों शायद ही इन दिनों उनकी आंतरिक संरचना बदल सकते हैं और मैं अपने खेतों सीधे इस्तेमाल कर सकते हैं कि होगा।

परिणाम आंतरिक समारोह के विस्तारित संस्करण है g_tree_find_node()से gtree.c। मुझे लगता है मैं पहले चाहते हैं, पिछले या निकटतम नोड है कि क्या नियंत्रित करने के लिए दो पैरामीटर जोड़ा। निकटतम नोड्स के लिए एल्गोरिथ्म जावा के से अलग है TreeMap, क्योंकि हमारे नोड अपनी मूल करने के लिए एक सूचक नहीं है। इकाई परीक्षण के साथ पूर्ण कोड यहाँ है: gtreeex.c

typedef enum {
    FIND_EXACT = 0,
    FIND_FLOOR = 0x2,
    FIND_CEIL  = 0x20,
    FIND_LOWER = (FIND_FLOOR + 1),
    FIND_HIGHER = (FIND_CEIL + 1)
} find_mode;

static GTreeNode *
g_tree_find_node_ex (GTree        *tree,
                  gconstpointer key,
                  GCompareDataFunc key_compare,
                  find_mode mode
                  )
{
    GTreeNode *node;
    gint cmp;
    GTreeNode *last_lesser_node = NULL;
    GTreeNode *last_greater_node = NULL;

    node = tree->root;
    if (!node)
        return NULL;

    while (1)
        {
            cmp = key_compare (key, node->key, tree->key_compare_data);
            if (cmp == 0) {
                if (mode == FIND_LOWER) {
                    cmp = -1;
                } else if (mode == FIND_HIGHER) {
                    cmp = 1;
                } else {
                    return node;
                }
            }

            if (cmp < 0)
                {
                    if (!node->left_child) {
                        if ( (mode & FIND_FLOOR) ) {
                            return last_lesser_node; /* can be null */
                        }
                        if ( (mode & FIND_CEIL) ) {
                            return node;
                        }
                        return NULL;
                    }

                    last_greater_node = node;
                    node = node->left;
                }
            else
                {
                    if (!node->right_child) {
                        if ( (mode & FIND_CEIL) ) {
                            return last_greater_node; /* can be null */
                        }
                        if ( (mode & FIND_FLOOR) ) {
                            return node;
                        }
                        return NULL;
                    }

                    last_lesser_node = node;
                    node = node->right;
                }
        }
}

बेहतर प्रदर्शन के लिए यह दो नए मानकों के बजाय पूर्वप्रक्रमक मैक्रो का उपयोग बदलने के लिए संभव है ifके साथ #ifशामिल हैं और बिट्स कई बार हेडर।

04/07/2017 को 17:47
का स्रोत उपयोगकर्ता

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more