C Копирование связанного списка с двумя указателями - PullRequest
0 голосов
/ 30 декабря 2018

Это для школьного проекта, и мне нужно закончить функцию, чтобы скопировать связанный список сотрудников, который выглядит следующим образом

typedef struct TEmployee
{
    struct TEmployee * m_Next;
    struct TEmployee * m_Bak;
    char * m_Name;
} TEMPLOYEE;

Это моя функция для копирования

TEMPLOYEE * cloneList(TEMPLOYEE * src)
{
    TEMPLOYEE* current = src;
    TEMPLOYEE* newList = NULL;
    TEMPLOYEE* tail = NULL;

    while(current != NULL)
    {
        if(newList==NULL)
        {
            newList = (TEMPLOYEE*)malloc(sizeof(TEMPLOYEE));
            newList -> m_Name = current -> m_Name;
            newList -> m_Next = NULL;
            newList -> m_Bak = NULL;
            tail = newList;
        }
        else
        {
            tail -> m_Next = (TEMPLOYEE*)malloc(sizeof(TEMPLOYEE));
            tail = tail -> m_Next;
            tail -> m_Name = current -> m_Name;
            tail -> m_Next = NULL;
            tail -> m_Bak = current -> m_Bak;
        }
        current = current -> m_Next;
    }

    return newList;
}

это работает нормально, но не копирует m_Bak должным образом, поэтому, когда я пытаюсь это утверждать, m_Next и m_Bak должны быть одинаковыми, но не

assert ( b && ! strcmp ( b -> m_Name, "Maria" ) && b -> m_Bak == b -> m_Next );

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 30 декабря 2018

это мое решение:

typedef struct TEmployee
{
    struct TEmployee * m_Next;
    struct TEmployee * m_Bak;
    char * m_Name;
} TEMPLOYEE;

void *Malloc(size_t size)
{
    void *ptr = NULL;
    if ((ptr = malloc(size)) == NULL)
    {
        perror("alloc");
        exit(1);
    }

    return ptr;
}

TEMPLOYEE *cloneList(TEMPLOYEE *src)
{
    TEMPLOYEE *newList = (TEMPLOYEE *)Malloc(sizeof(TEMPLOYEE));
    newList->m_Bak = NULL;

    TEMPLOYEE *copy = newList;
    TEMPLOYEE *current = src;

    while (current != NULL)
    {
        newList->m_Name = strdup(current->m_Name);  // need free
        newList->m_Next = NULL;

        if (current = current->m_Next)
        {
            newList->m_Next = (TEMPLOYEE *)Malloc(sizeof(TEMPLOYEE));
            newList->m_Next->m_Bak = newList;
            newList = newList->m_Next;
        }
    }

    return copy;
}

Надеюсь, я правильно понимаю вашу проблему ...

0 голосов
/ 30 декабря 2018

Эта строка

tail -> m_Bak = current -> m_Bak;

неверна, поскольку заставляет новый список указывать обратно на текущий список.

Вам скорее нужно:

    else
    {
        tail -> m_Next = (TEMPLOYEE*)malloc(sizeof(TEMPLOYEE));
        tail -> m_Next -> m_Bak = tail;  // New line
        tail = tail -> m_Next;
        tail -> m_Name = current -> m_Name;
        tail -> m_Next = NULL;
        // tail -> m_Bak = current -> m_Bak; Delete this line
    }

Обратите внимание, чтоВаш код не копирует имена, поэтому оба списка будут указывать на один и тот же объект имени.Если вы хотите сделать реальную копию имен, взгляните на strdup

Также обратите внимание:

Вам не нужно приводить значение, возвращаемое malloc.Однако вам следует проверить, вернул ли malloc NULL

...