Nobody Noname
Nobody Noname

Reputation: 91

Delete duplicates from linked list and save it to another list in C

I encountered a problem during this task. I'm just take list, check that currently processed element is in it. If is skip it, else add to new list. I wrote three function to do this. One that search particular element, next which is checking for element exist in new list, and the last which is get everything together.

I've tried to do this in two ways:

Here is the code:

struct list *search_node(struct list *prt, char *to_search) {
    is_empty();
    short is_found = -1;
    while (prt != NULL && ((is_found = strcmp(prt->word, to_search) != 0))) {
        prt = prt->next;
    }
    if (!is_found)
        return prt;
    else
        return NULL;
}

bool is_on_list(struct list *ptr, char *str) {
    if (search_node(ptr, str) != NULL)
        return 1;
    else
        return 0;
}

struct list *without_repetiton(struct list *head) {
    struct list *new_list = NULL;
    struct list **new_el = &new_list;
    struct list *prt1 = head, *check;

    while (prt1 != NULL) {
        //printf("test = %s\n", prt1 -> word);
        check = new_list;
        if (!is_on_list(prt1->next, prt1->word)) { // or (new_list, prt1 -> word) 
            *new_el = (struct list *)malloc(sizeof(struct list));
            memcpy(*new_el, prt1, sizeof(struct list));
            new_el = &((*new_el)->next);
        }
        prt1 = prt1->next;
    }
    return new_list;
}

There is the structure of list:

struct list {
    char *word;
    struct list *next;
    struct list *prev;
};

I have two questions, first why the first approach writes the list in descending order, and second why when I've tried to search occurrence of word in already created list in not work?

IO samples:

When : is_on_list(prt1->next, prt1->word))
Fist list: One, One, Two
Second list: Two, One
When : is_on_list(new_list, prt1->word))
The first list is the same as second.

Upvotes: 3

Views: 65

Answers (1)

chqrlie
chqrlie

Reputation: 145307

Your code does not construct the duplicate list correctly: simplify the code and link the new elements by hand instead of using memcpy():

struct list *search_node(struct list *ptr, const char *to_search) {
    while (ptr != NULL) {
        if (!strcmp(ptr->word, to_search))
            return ptr;
    }
    return NULL;
}

bool is_on_list(struct list *ptr, const char *str) {
    return search_node(ptr, str) != NULL;
}

struct list *without_repetiton(struct list *head) {
    struct list *new_list = NULL;
    struct list *tail = NULL;

    for (struct list *ptr = head; ptr != NULL; ptr = ptr->next) {
        if (!is_on_list(new_list, ptr->word)) {
            struct list *node = malloc(sizeof(*node));
            node->next = NULL;
            node->prev = tail;
            node->str = strdup(ptr->word);
            if (tail == NULL) {
                 new_list = tail = node;
            } else {
                 tail->next = node;
                 tail = node;
            }
        }
    }
    return new_list;       
}

Upvotes: 1

Related Questions