重新定位单链接列表中的节点会创建无限循环

时间:2016-06-22 19:54:25

标签: c linked-list singly-linked-list relocation

在我的作业中,我被要求通过他的名字字段将特定节点重新定位到特定索引。我无法弄清楚为什么我的列表会变成无限列表。问题在于函数“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 个答案:

答案 0 :(得分:0)

changePlacement()末尾的代码并不代表oldNodenewNode彼此相邻的情况,i。即即G。 nodeAfterNewNode = newNode->nextoldNode相同。 (除了它没有找到没有找到名字的情况。)更换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;