Перемещение узла в односвязном списке создает бесконечный цикл

В моей домашней работе меня попросили переместить определенный узел по полю его имени в определенный индекс. У меня проблемы с выяснением, почему мой список становится бесконечным списком. Проблема в функции "changePlacement"
Пример:
Данный связанный список: 1->2->3->4
Выход: 1->3->3->3...
Ожидаемый результат: 1->3->2->4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Frame
{
    char            *name;
    unsigned int    duration;
    char            *path;  // may change to FILE*
};
typedef struct Frame frame_t;

struct Link
{
    frame_t *frame;
    struct Link *next;
};
typedef struct Link link_t;

int listLen = 0;
link_t* lastNode = NULL;

void addFrame(link_t** list);
void frameData(frame_t* frame);
void freeVideo(link_t* video);
void showList(link_t* list);
void freeNode(link_t* list);
void changePlacement(link_t** list, int newIndex, char* name);

int main(void)
{
    link_t* video = NULL;
    lastNode = video;
    if (!video)
    {
        perror(video);
    }
    addFrame(&video);
    addFrame(&video);
    addFrame(&video);
    addFrame(&video);

    showList(video);
    changePlacement(&video, 2, "3");
    showList(video);
    printf("\n");
    freeVideo(&video);

    _flushall();
    getchar();
    return 0;
}



void addFrame( link_t** video)
{
    char strTemp[200] = { 0 };

    link_t* newFrame = (link_t*) calloc(1, sizeof(link_t));
    newFrame->frame = (frame_t*) malloc(sizeof(frame_t));

    printf("                  *** Creating new frame ***\n");
    printf("Please insert a frame path:\n");
    scanf(" %s", &strTemp);
    newFrame->frame->path = (char*) calloc(strnlen(strTemp, 200) + 1, sizeof(char));
    strncpy(newFrame->frame->path, strTemp, strnlen(strTemp, 200));

    printf("Please insert frame duration(in miliseconds):\n");
    scanf(" %d", &(newFrame->frame->duration));

    printf("Please choose a name for that frame:\n");
    scanf(" %s", &strTemp);
    newFrame->frame->name = (char*) calloc(strnlen(strTemp, 200) + 1, sizeof(char));
    strncpy(newFrame->frame->name, strTemp, strnlen(strTemp, 200));

    if (!(*video))
    {
        (*video) = newFrame;
    }
    else
    {
        lastNode->next = newFrame;
    }
    lastNode = newFrame;


    ++listLen;
}




void freeVideo(link_t** video)
{
    link_t* currNode = NULL;
    int loop = 0;

    for (; currNode; currNode = *video) // set curr to head, stop if list empty.
    {
        // advance head to next element.
        freeNode(currNode);
        (*video) = (*video)->next; // delete saved pointer.
    }
    freeNode((*video)->next);
    freeNode((*video));


}


void showList(link_t* list)
{
    printf("\n\t|Name\t\t|    Duration   |     Path\n");
    printf("\t+++++++++++++++++++++++++++++++++++++++++++++++\n");
    for (;list; list = list->next)
    {
        printf("\t|%10s\t|%10d\t|\t%s\n", list->frame->name, list->frame->duration, list->frame->path);
        printf("\t+++++++++++++++++++++++++++++++++++++++++++++++\n");
    }
}

void freeNode(link_t* node)
{
    free(node->frame->name);
    free(node->frame->path);
    free(node->frame);
    free(node);
}

void changePlacement(link_t** list, int newIndex, char* name)
{
    link_t *prevOldNode = (*list), *prevTemp = NULL, *oldNode = NULL, *newNode = NULL;
    link_t *temp = (*list), *PrevNewNode = NULL, *nodeAfterNewNode = NULL;
    int currIndex = 0, i = 0, flag = 0;

    while ((temp->next))
    {
        ++currIndex;
        if (!strcmp(temp->frame->name, name)) //looking for the wanted node
        {
            oldNode = temp;
            prevOldNode = prevTemp;
        }
        if (currIndex == newIndex)
        {
            PrevNewNode = prevTemp;
            newNode = temp;
        }
        prevTemp = temp;
        temp = temp->next;
    }
    nodeAfterNewNode = newNode->next; //temporal variable that stores the node after the new node
    prevOldNode->next = oldNode->next;
    newNode->next = oldNode;

    oldNode->next = nodeAfterNewNode;
}

У вас есть идеи после просмотра моего кода? любая помощь будет благословлена

1 ответ

Ваш код в конце changePlacement() не учитывает случай oldNode а также newNode быть рядом друг с другом, т.е. nodeAfterNewNode = newNode->next быть идентичным oldNode, (Кроме того, это не относится к случаю отсутствия имени.) Гораздо проще просто поменять frame указатели; менять

    nodeAfterNewNode = newNode->next; //temporal variable that stores the node after the new node
    prevOldNode->next = oldNode->next;
    newNode->next = oldNode;

    oldNode->next = nodeAfterNewNode;

в

    if (!oldNode) return;   // wanted node name not found
    frame_t *f = oldNode->frame;
    oldNode->frame = newNode->frame;
    newNode->frame = f;
Другие вопросы по тегам