【问题标题】:Binary Tree storing any data type in c在c中存储任何数据类型的二叉树
【发布时间】:2014-11-07 20:53:35
【问题描述】:

我目前正在 c 中实现二叉树。在让代码工作以插入整数之后,我现在希望树能够存储任何日期类型,即 char 等。我对如何去做这件事有点难过。我听说/看到我可以在我的节点结构中使用 void*,但不确定如何在插入元素和比较 void* 以查看哪个更大或更小方面实现这一点。任何帮助将不胜感激!谢谢

 #include <stdio.h>
 #include <stdlib.h>

//struct for node of the binary tree
struct node
{
    void *value;
    struct node *p_left;
    struct node *p_right;
};

//recursive function to allow users to input into the tree
void insert(void* key, struct node** leaf )
{

if( *leaf == NULL )
{
    *leaf = (struct node*) malloc( sizeof( struct node ) );
    (*leaf)->value = key;
    (*leaf)->p_left = NULL;
    (*leaf)->p_right = NULL;
    printf(  "\nnew node " );
}
else if( key < (*leaf)->value )
   {
    printf(  "\ngoing left " );
    insert( key, &(*leaf)->p_left );

   }
else if(key > (*leaf)->value)
   {
    printf(  "\ngoing right " );
    insert( key, &(*leaf)->p_right );
   }
}

int main(void)
{
struct node *p_root = NULL;
int value ; //i want value to be of any kind

printf(  "\nPlease enter a value: " );
scanf( "%d", &value );
insert(value,  &p_root);

return 0;
   }

【问题讨论】:

  • 比较是困难的部分,您必须想出一种方法来比较不同类型的元素,即如何比较字符串和浮点数?我认为在您开始编写该部分之前要尝试并弄清楚这一点。
  • 通过创建比较函数传递给insert函数(int cmpInt(const void*, const void*),int cmpStr(const void*, const void*))。
  • 非常感谢@BLUEPIXY,您能否解释一下这条线的工作原理:return *a &lt; *b ? -1 : *a &gt; *b;

标签: c pointers tree binary-tree void


【解决方案1】:

您应该使用 void 指针来插入值,然后将它们转换为它们假定的类型。

问题是,如果您知道以后要比较哪个更大或更小,您就不想得到“任何东西”。我想你可能想在你的节点中有一个额外的信息来指定实际的值是什么类型。

我想你想这样做是为了练习,但实际上你真的想将字符数组与整数进行比较吗?

【讨论】:

  • 感谢您的回复。是的,这只是为了练习,我应该在插入函数中投射它们吗?对不起,我对指针很陌生
【解决方案2】:
#include <stdio.h>
#include <stdlib.h>

struct node {
    void *value;
    struct node *p_left;
    struct node *p_right;
};

typedef int (*Compare)(const void *, const void *);

void insert(void* key, struct node** leaf, Compare cmp){
    if( *leaf == NULL ){
        *leaf = (struct node*) malloc( sizeof( struct node ) );
        (*leaf)->value = key;
        (*leaf)->p_left = NULL;
        (*leaf)->p_right = NULL;
        printf(  "\nnew node " );
    } else if( cmp(key,  (*leaf)->value) < 0) {
        printf(  "\ngoing left " );
        insert( key, &(*leaf)->p_left, cmp);
    } else if( cmp(key, (*leaf)->value) > 0){
        printf(  "\ngoing right " );
        insert( key, &(*leaf)->p_right, cmp);
    } else {
        free(key);
    }
}

int CmpInt(const int *a, const int *b){
    return *a < *b ? -1 : *a > *b;
}

int *GetInteger(void){
    char line[16];
    printf("Please enter a value : ");
    if(fgets(line, sizeof line, stdin)){
        int v, *ret;
        char *p;
        v = strtol(line, &p, 10);
        if(*p == '\n' || *p == '\0'){
            int *ret = malloc(sizeof(*ret));
            *ret = v;
            return ret;
        }
    }
    return NULL;
}

void print_tree(struct node *root, void (*print_func)(const void*) ){
    if(root){
        print_tree(root->p_left, print_func);
        print_func(root->value);
        print_tree(root->p_right, print_func);
    }
}

void print_int(const void *p){
    printf("%d ", *(int*)p);
}

int main(void){
    struct node *p_root = NULL;
    void *value;//int *value;

    while(value = GetInteger()){//upto input EOF or invalid input
        insert(value,  &p_root, (Compare)CmpInt);
    }

    print_tree(p_root, print_int);
    //release tree omit 
    return 0;
}

【讨论】:

  • 非常感谢@BLUEPIXY,您能否解释一下这条线的工作原理:return *a &lt; *b ? -1 : *a &gt; *b;
  • @JamieConnelly if(*a &lt; *b) return -1; if(*a &gt; *b) return 1;if(*a==*b) return 0;
  • *a &gt; *b不满足时为0,满足C中的条件表达式时为1
  • 好的,太好了。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 1970-01-01
  • 2012-03-17
  • 1970-01-01
  • 2011-12-20
  • 1970-01-01
相关资源
最近更新 更多