2012-11-21 29 views
2

我試圖穿越使用twalk()一個二叉樹<search.h>twalk沒有全局

#define _GNU_SOURCE  /* Expose declaration of tdestroy() */ 
    #include <search.h> 
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <time.h> 

    void *root = NULL; 

    void * 
    xmalloc(unsigned n) 
    { 
     void *p; 
     p = malloc(n); 
     if (p) 
      return p; 
     fprintf(stderr, "insufficient memory\n"); 
     exit(EXIT_FAILURE); 
    } 

    int 
    compare(const void *pa, const void *pb) 
    { 
     if (*(int *) pa < *(int *) pb) 
      return -1; 
     if (*(int *) pa > *(int *) pb) 
      return 1; 

     return 0; 
    } 

    void 
    action(const void *nodep, const VISIT which, const int depth) 
    { 
     int *datap; 

     switch (which) { 
     case preorder: 
      break; 
     case postorder: 
      datap = *(int **) nodep; 
      printf("%6d\n", *datap); 
      break; 
     case endorder: 
      break; 
     case leaf: 
      datap = *(int **) nodep; 
      printf("%6d\n", *datap); 
      break; 
     } 
    } 

    int 
    main(void) 
    { 
     int i, *ptr; 
     void *val; 

     srand(time(NULL)); 
     for (i = 0; i < 12; i++) { 
      ptr = (int *) xmalloc(sizeof(int)); 
      *ptr = rand() & 0xff; 
      val = tsearch((void *) ptr, &root, compare); 
      if (val == NULL) 
       exit(EXIT_FAILURE); 
      else if ((*(int **) val) != ptr) 
       free(ptr); 
     } 
     twalk(root, action); 
     tdestroy(root, free); 
     exit(EXIT_SUCCESS); 
    } 

正如你可以看到有沒有辦法傳遞給或返回從行動的任何變量()。 爲什麼如此密封?我不能使用任何全局的,因爲程序使用線程,我的問題是:我如何在線程安全模式下遍歷(並與非全局變量共享nodep)? 原諒我的英語不好

編輯: 作爲開卷說,解決辦法是重新發明這個特殊的輪子,重新定義在tsearch.c所用的結構解決了這個問題:

/* twalk() fake */ 

struct node_t 
{ 
    const void *key; 
    struct node_t *left; 
    struct node_t *right; 
    unsigned int red:1; 
}; 

static void tmycallback(const xdata *data, const void *misc) 
{ 
    printf("%s %s\n", (const char *)misc, data->value); 
} 

static void tmywalk(const struct node_t *root, void (*callback)(const xdata *, const void *), const void *misc) 
{ 
    if (root->left == NULL && root->right == NULL) { 
     callback(*(xdata * const *)root, misc); 
    } else { 
     if (root->left != NULL) tmywalk(root->left, callback, misc); 
     callback(*(xdata * const *)root, misc); 
     if (root->right != NULL) tmywalk(root->right, callback, misc); 
    } 
} 

/* END twalk() fake */ 

if (root) tmywalk(root, tmycallback, "Hello walker"); 

回答

4

我猜除了那些指定和實施功能的人之外,沒有人能夠完全回答「爲什麼」。我猜「短視」,或者「歷史原因」(他們在線程編程成爲普通事物之前就這樣做了)。

無論如何,由於這個限制,對我來說這個API似乎有點「玩味」,因爲實際上所有的API都沒有包含用戶擁有的void *,這只是在API和任何回調之間不透明地傳遞。

所以,我想這個解決方案是重新發明這個特定的輪子,並編寫自己的函數來遍歷二叉樹。

+0

明白了,看編輯:) –