简体   繁体   中英

How to make a nested list in C using a single linked list struct format which contains a void pointer and a recursive pointer to the struct?

The task is to sort an existing list by length into another nested list.

["x", "yy", "zzz", "f", "gg"] ergeben 
 [["x", "f"], ["yy",
"gg"], ["zzz"]] 

I am thinking of using the void pointer in Struct Node to store another list ie list within each node of the main list. But i keep getting the following error

dereferencing 'void *' pointer

I tried typecasting too. There might be other issues, but I haven't gotten there yet because of the above issue.

typedef struct Node {
    void *value;
    struct Node *next; // self-reference
} Node;

// Group elements in list. Equivalent elements (for which equivalent is true) are put
// in the same group. The result is a list of groups. Each group is itself a list.
// Each group contains items that are equivalent.

Node *group_list(Node *list, EqualFun equivalent) {
    
    Node *list_new = malloc(sizeof(Node));
    //list_new = NULL;
    list_new->next = NULL;
    (Node *)list_new->value = malloc(sizeof(Node));
    (char *)(list_new->value->value) = list->value;
    list_new->value->next = NULL;
    Node *temp1 = list->next;
    
    Node *list_tester1 = list_new;
    Node *list_tester2 = list_new;
    
    while (list_new != NULL) {
        
        while (temp1 != NULL) {  //for the list inside list_new
            list_tester2 = list_tester1;
            if (equivalent(list_new->value->value, temp1->value)) {
                list_new->value = append_list(list_new->value, temp1->value);
            } else {     
                while (list_tester2 != NULL) { // for outer list
                    if (!equivalent(list_tester2->value->value, temp1->value)) {
                        list_new = append_list(list_new->value, temp1->value);
                        list_new = append_list(list_tester2->value, temp1->value);
                        list_new = append_list(list_tester1->value, temp1->value);       
                    }        
                    list_tester2 = list_tester2->next;   
                }
            }
            list_new = list_new->next;
        }
    }
    return list_new;
}

If a maximum word length (and therefore the maximum number of sub-lists) is known at compile-time, you could create an array of pointers to the heads of the individual sub-lists. The first element of the array would point to the sub-list with words of length one, the second element of the array would point to the sub-list with words of length two, etc.

If you want to have a linked list of linked lists (ie a nested linked list) instead, then you will have to create two types of nodes. One type of node will be for the main linked list and one type of node will be for the sub-lists.

For example, you could define the following two structs:

struct SubListNode
{
    char *word;
    struct SubListNode *next;
};

struct MainListNode
{
    struct SubListNode *head_of_sublist;
    struct MainListNode *next;
};

I see no reason to use a void pointer in this case, as the type of the referenced object is always known.

Although it is possible for both lists to share the same struct by using a void pointer, so that you only have to declare one struct , I see no benefit in doing so. Whenever dereferencing the void pointer, you will have to cast it to the appropriate type it is pointing to. This will make your code much more complicated than simply declaring a second type of struct .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM