函数swapNode在双向链表中不起作用

问题描述 投票:0回答:1

功能swapNode交换列表中的2个节点。函数创建node* temp以存储临时数据,然后交换node* Anode* B的数据。我不明白为什么它不起作用。下面是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
struct node;
struct list;

typedef struct node node;
typedef struct list list;

struct node
{
    int point;
    char name[30];
    node *next;
    node *prev;
};

struct list
{
    node *head;
    node *tail;
    int count;
};

node *allocateNewNode(int point, char name[30], node *prev, node *next);
list *createList();
bool insertHead(list *listNode, int point, char name[30]);
bool compareName(char a[30], char b[30]);
bool swapNode(list *listNode, char nameA[30], char nameB[30]);

int main()
{
    list *listNode = createList();

    insertHead(listNode, 10, "abc def");
    insertHead(listNode, 9, "qwe rty");
    insertHead(listNode, 8, "ui op");
    insertHead(listNode, 30, "fgh jkl");
    insertHead(listNode, 1234, "akaka");

    swapNode(listNode, "ui op", "abc def");

    node *temp = listNode->head;
    while (temp != NULL)
    {
        printf("%-20s%d\n", temp->name, temp->point);
        temp = temp->next;
    }
    free(temp);
    printf("\n%d", listNode->count);
    return 0;
}

node *allocateNewNode(int point, char name[30], node *prev, node *next)
{
    node *newNode = (node *)malloc(sizeof(node));
    newNode->point = point;
    strcpy(newNode->name, name);
    newNode->next = next;
    newNode->prev = prev;
    return newNode;
}

list *createList()
{
    list *listNode = (list *)malloc(sizeof(list));
    listNode->count = 0;
    listNode->head = NULL;
    listNode->tail = NULL;
    return listNode;
}

bool insertHead(list *listNode, int point, char name[30])
{
    node *newNode = allocateNewNode(point, name, NULL, listNode->head);
    if (listNode->head)
        listNode->head->prev = newNode;
    listNode->head = newNode;
    if (listNode->tail == NULL)
        listNode->tail = newNode;
    ++listNode->count;
    return true;
}
bool compareName(char a[30], char b[30])
{
    for (int i = 0; i < 31; i++)
    {
        if (a[i] != b[i])
            return false;
        if (a[i] == '\0')
            break;
    }

    return true;
}

bool swapNode(list *listNode, char nameA[30], char nameB[30])
{
    node *A = NULL, *B = NULL;
    node *temp = listNode->head;

    for (int i = 0; i < listNode->count - 1; i++)
    {
        if (compareName(temp->name, nameA))
            A = temp;
        else if (compareName(temp->name, nameB))
            B = temp;
        temp = temp->next;
        if (A || B)
            break;
    }
    if (!A || !B)
        return false;
    else if (A == B)
        return false;

    *temp = *A;
    *A = *B;
    *B = *temp;

    if (A->prev)
        A->prev->next = A;
    if (A->next)
        A->next->prev = A;
    if (A->prev)
        A->prev->next = A;
    if (A->next)
        A->next->prev = A;
    free(temp);
    return true;
}

感谢您的帮助

c data-structures swap doubly-linked-list
1个回答
1
投票

swapNode中,AB最初是NULL。找到两个节点中的一个时,搜索两个匹配节点的循环会提前终止:

        if (A || B)
            break;

当循环终止时,AB最多为非NULL,因此AB至少之一为NULL。这将导致函数返回false

    if (!A || !B)
        return false;

为避免这种情况,当AB都为非NULL时,应更改循环以使其中断:

        if (A && B)
            break;

而且,循环仅检查列表的count - 1个元素,因此它忽略了最后一个元素:

    for (int i = 0; i < listNode->count - 1; i++)

要检查所有元素,您需要将其更改为:

    for (int i = 0; i < listNode->count; i++)

或者,您可以忽略listNode->count,而是检查temp指针:

    while (temp != NULL)

这将起作用,因为将temp初始化为listNode->head,对于空列表,对于非空列表,其将为NULL,列表中最后一个元素的next成员为NULL ],因此temp = temp->next;将在检查完最后一个元素后将temp设置为NULL


0
投票

使用调试器,您会看到函数swapNode返回于

    if (!A || !B)
        return false;

如果您设置了for循环,则当设置了breakA中的至少一个,即找到第一个匹配节点时,您会看到从循环中获得B

        if (A || B)
            break;

将此更改为

        if (A && B)
            break;
© www.soinside.com 2019 - 2024. All rights reserved.