功能swapNode
交换列表中的2个节点。函数创建node* temp
以存储临时数据,然后交换node* A
和node* 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;
}
感谢您的帮助
在swapNode
中,A
和B
最初是NULL
。找到两个节点中的一个时,搜索两个匹配节点的循环会提前终止:
if (A || B)
break;
当循环终止时,A
和B
最多为非NULL,因此A
和B
至少之一为NULL。这将导致函数返回false
:
if (!A || !B)
return false;
为避免这种情况,当A
和B
都为非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
。
使用调试器,您会看到函数swapNode
返回于
if (!A || !B)
return false;
如果您设置了for
循环,则当设置了break
和A
中的至少一个,即找到第一个匹配节点时,您会看到从循环中获得B
。
if (A || B)
break;
将此更改为
if (A && B)
break;