2012-10-11 3 views
0

Есть ли способ написать одну функцию (addnode) для разных структур? Я такой сценарий:Функция addnode для различных структур связанных списков

typedef struct linkedlist_a *ptr_a; 
typedef struct linkedlist_a 
{ 
    /* content */ 
    ptr_a next; 
} listA; 

typedef struct linkedlist_b *ptr_b; 
typedef struct linkedlist_b 
{ 
    /* content */ 
    ptr_b next; 
} listB; 

listA *listA_addnode(listA *head, listA *node) 
{ 
    listA *temp = head; 
    if(temp == NULL) 
    { 
     temp = node; 
    } 
    else if(temp -> next == NULL) 
    { 
     temp -> next = node; 
    } 
    else 
    { 
     while(temp -> next) temp = temp -> next; 
     temp -> next = node;   
    } 

    return head; 
} 


listB *listB_addnode(listB *head, listB *node) 
{ 
    listB *temp = head; 
    if(temp == NULL) 
    { 
     temp = node; 
    } 
    else if(temp -> next == NULL) 
    { 
     temp -> next = node; 
    } 
    else 
    { 
     while(temp -> next) temp = temp -> next; 
     temp -> next = node;   
    } 

    return head; 
} 

Если есть два structuress нормально для меня написать две функции, но в этом случае я имею более чем 2, как я могу сделать?

+0

Вы объявляя две различные связные списки для хранения различных типов? – Ifthikhan

+0

, если вы вызываете функцию addnode() в пустом списке, это не сработает - вам нужно изменить голову, чтобы указать на недавно выделенный узел – Raj

ответ

1

Вместо того, чтобы иметь разные struct s, которые представляют собой связанный список, возможным решением будет иметь один связанный список struct, который имеет void* член для данных. Это позволило бы использовать одну функцию add_node() с несколько иной подписью.

Например:

struct linked_node 
{ 
    void* data; 
    struct linked_node* next; 
}; 

void add_node(struct linked_node** a_head, void* a_data) 
{ 
    struct linked_node* new_node = malloc(sizeof(*new_node)); 
    new_node->data = a_data; 
    new_node->next = 0; 
    if (!*a_head) 
    { 
     *a_head = new_node; 
    } 
    else 
    { 
     /* ... */ 
    } 
} 

Существует опасность того, при таком подходе, а именно в правильной интерпретации data элемента. Однако с осторожностью этот подход будет соответствовать вашим требованиям.

Пример использования (проверка ошибок опущена):

struct data_x { int i; char c; }; 
struct data_y { char* s; }; 

struct linked_node* list_x = 0; 
struct data_x* dx = malloc(sizeof(*dx)); 
dx->i = 4; 
dx->c = 'a'; 

add_node(&list_x, dx); 

if (list_x) 
{ 
    struct data_x* x = list_x->data; 
    printf("x.i=%d x.c=%c\n", x->i, x->c); 
} 

struct linked_node* list_y = 0; 
struct data_y* dy = malloc(sizeof(*dy)); 
dy->s = "hello"; 

add_node(&list_y, dy); 

if (list_y) 
{ 
    struct data_y* y = list_y->data; 
    printf("y.s=%s\n", y->s); 
} 

Смотреть онлайн демо http://ideone.com/iZO8h.

+0

«Данные» могут быть структурой-оболочкой, которая включает информацию о значении и типе который позволит вам вывести и бросить во время выполнения. – Ifthikhan

+0

Большое спасибо, это было то, что я искал. – wsknorth

0

Только способ сделать это с помощью макроса, предполагая, что ваши связывающие элементы называются одинаковыми (next присутствует во всех типах, которые вы хотите пройти там).

кода стиля GNU вперед: -std=gnu98 или выше

#define addnode(head, node) ({\ 
    typeof(head) _head = (head);\ 
    typeof(node) _node = (node);\ 
    if(_head == NULL)\ 
    {\ 
     _head = _node;\ 
    }\ 
    else\ 
    {\ 
     while(_head -> next) _head = _head -> next;\ 
     _head -> next = _node;  \ 
    }\ 
    \ 
    _head;\ 
}) 

Это очень плохой стиль программирования, хотя

Смежные вопросы