简体   繁体   中英

Merging two linked lists

I have a task where I have to combine 2 linked list in a function in ascendent order without creating a new list. Something like this: [1.3-->3.2-->4.6-->7.0] & [2.7-->2.9-->5.1] -> [1.3-->2.7-->2.9-->3.2-->4.6-->5.1-->7.0] . I have the whole code but the monitoring program keep reporting the same: MEMORY LEAK .

This is my code (only the function part, and the struct definition):

typedef struct _listelem {
    double data;
    struct _listelem *next;
} listelem;

listelem *merge(listelem *a, listelem *b) {
    listelem *lemarado = NULL;
    listelem *mozgo = a;
    listelem *elol2 = b;
    lemarado = mozgo;
    if (elol2 == NULL)  // if the list is zero
        return a;
    else
    if (mozgo == NULL)
        return b;
    if (mozgo->next == NULL) { //if the first list has only one element
        while (elol2 != NULL) {
            listelem *vege;
            vege = (listelem *)malloc(sizeof(listelem));
            vege->data = elol2->data;
            lemarado->next = vege;
            free(vege);
            lemarado = lemarado->next;
            elol2 = elol2->next;
        }
        lemarado->next = NULL;
        return a;
    }
    mozgo = mozgo->next; // I am maintaining a pointer which points to the next data, and a pointer
    while (mozgo != NULL) { // Which points to the data before, and I stick an element between them
        if (elol2 == NULL) {
            while (mozgo != NULL)
                mozgo = mozgo->next;
            while (lemarado != NULL)
                lemarado = lemarado->next;
            return a;
        }
        if (mozgo->data > elol2->data) {
            listelem *hozzafuz;
            hozzafuz = (listelem *)malloc(sizeof(listelem));
            hozzafuz->data = elol2->data;
            lemarado->next = hozzafuz;
            hozzafuz->next = mozgo;
            elol2 = elol2->next;
            lemarado = lemarado->next;
        } else {
            mozgo = mozgo->next;
            lemarado = lemarado->next;
        }
        if (mozgo == NULL) {
            while (elol2 != NULL) {
                listelem *vege;
                vege = (listelem *)malloc(sizeof(listelem));
                vege->data = elol2->data;
                lemarado->next = vege;
                free(vege);
                lemarado = lemarado->next;
                elol2 = elol2->next;
            }
            lemarado->next = NULL;
        }
    }
    return a;
}

There is no need to allocate of free list nodes, you are just supposed to merge the sorted lists into a single list. Using non-English variable names is confusing for people who do not speak Hungarian, which I'm afraid is very common.

Here is a modified version:

typedef struct _listelem {
    double data;
    struct _listelem *next;
} listelem;

listelem *merge(listelem *a, listelem *b) {
    listelem *head = NULL;
    listelem *tail = NULL;

    if (b == NULL)
        return a;
    else
    if (a == NULL)
        return b;
    if (a->data <= b->data) {
        head = a;
        a = a->next;
    } else {
        head = b;
        b = b->next;
    }
    tail = head;
    while (a != NULL && b != NULL) {
        if (a->data <= b->data) {
            tail->next = a;
            a = a->next;
        } else {
            tail->next = b;
            b = b->next;
        }
        tail = tail->next;
    }
    if (a == NULL)
        tail->next = b;
    else
        tail->next = a;

    return head;
}

If you master double pointers, the above code can be simplified as:

listelem *merge(listelem *a, listelem *b) {
    listelem *head = NULL;
    
    for (listelem **link = &head;; link = &(*link)->next) {
        if (a == NULL) {
            *link = b;
            break;
        }
        if (b == NULL) {
            *link = a;
            break;
        }
        if (a->data <= b->data) {
            *link = a;
            a = a->next;
        } else {
            *link = b;
            b = b->next;
        }
    }
    return head;
}       
struct thing *merge(struct thing *one,struct thing *two)
{
struct thing *result;
struct thing **pp; // will always point to the _pointer_ that will be assigned the next node.

result=NULL;
for(pp = &result; one && two; pp = &(*pp)->next) {
        if(one->value <= two->value) {
                *pp = one; one = one->next;
                }
        else    {
                *pp = two; two = two->next;
                }
        }
        
        // When we get here,  one and/or two will be NULL
*pp = (one) ? one : two;
        
return result;
}       
        

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