我在 C 中成对交换链表的代码有什么问题?

What is wrong with my code for Pairwise swapping of linked list in C?

这是我的配对代码:

#include<stdio.h>
#include<stdlib.h>
struct Node{
     int data;
     struct Node *next; 
};
int main(){
struct Node *list, *head;
head = (struct Node *)malloc(sizeof(struct Node));
list = head;
int i;
for(i=0;i<6;i++){
    list->data=i;
    list->next = (struct Node *)malloc(sizeof(struct Node));
    list = list->next;
 }
list->next = NULL;
list = head;
while(list->next->next!=NULL){
    int temp = list->data;
    list->data = list->next->data;
    list->next->data = temp;
    list = list->next->next;
 }
 printf("Pair swapped list: ");
 while(head->next!=NULL){
       printf("%d\n",head->data);
        head=head->next;
  }
 return 0;
}

我有两个问题。主要是这段代码给出了运行时错误,我不明白为什么。第二件事是,如果我使用 list = NULL 而不是 list->next = null 然后 while(list!=NULL) 那么它会导致无限循环。如果代码保持不变,最后会创建一个垃圾元素。请帮助我。

引起问题的行是:

while(list->next->next!=NULL) {

list->nextNULL

时你不用处理

所以,只需将其替换为:

while(list->next != NULL && list->next->next != NULL) {

对于第二个问题,正如 DevSolar 所指出的,您必须更好地控制列表创建:

struct Node *list, *head, *last;
head = list = last = NULL; 

for (i=0; i<6; i++)
{
    /* create a node */
    list = malloc(sizeof *list);

    /* if head is not set, set it */
    if (NULL == head)
        head = list;

    /* fill new element */
    list->data = i;
    list->next = NULL;

    /* this new node is the child of the previous */
    if (NULL != last)
        last->next = list;     

     /* remember last created node */
    last = list;
}

您有 7 个节点 -- head,以及您在循环中创建的 6 个。

您的 while 检查 list->next->next!=NULL,并在循环结束时像这样移动 listlist = list->next->next;

这意味着您的循环运行:

  • 第一个节点,与第二个交换
  • 第 3 个节点,与第 4 个交换
  • 第 5 个节点,与第 6 个节点交换。

然后list设置为第7个节点(list->nextNULL)。您的 while 检查 list->next->next。如前所述,list->nextNULLlist->next->next 是非法内存访问(取消引用 NULL)。

(关于你应该做的事情请遵从 purplepsycho -- 我不会从其他人的答案中复制。;-))

对于根据 C 标准的初学者,不带参数的函数 main 应声明为

int main( void )

在这个循环中

for(i=0;i<6;i++){
    list->data=i;
    list->next = (struct Node *)malloc(sizeof(struct Node));
    list = list->next;
 }
list->next = NULL;

分配了一个具有不确定数据成员值的冗余节点data

这个while循环中的条件

while(list->next->next!=NULL){
    int temp = list->data;
    list->data = list->next->data;
    list->next->data = temp;
    list = list->next->next;
 }

是错误的,并且由于循环结束时的这条语句而导致未定义的行为

    list = list->next->next;

条件应该这样写

while ( list && list->next )

使用您的方法,程序可以看起来像下面这样

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

struct Node
{
    int data;
    struct Node *next; 
};

int main(void) 
{
    struct Node *list, *head;
    const int N = 6;

    head = ( struct Node * )malloc( sizeof( struct Node ) );
    list = head;

    int i = 0;
    do
    {
        list->data = i;
    } while ( ++i < N && ( list = list->next = ( struct Node *)malloc( sizeof( struct Node ) ) ) );

    list->next = NULL;

    printf("Original list: ");
    for ( list = head; list; list = list->next )
    {
        printf( "%d ", list->data );
    }
    putchar( '\n' );

    list = head;

    while ( list && list->next )
    {
        int temp = list->data;
        list->data = list->next->data;
        list->next->data = temp;
        list = list->next->next;
    }

    printf("Pair swapped list: ");
    for ( list = head; list; list = list->next )
    {
        printf( "%d ", list->data );
    }
    putchar( '\n' );

    return 0;
}

它的输出是

Original list: 0 1 2 3 4 5 
Pair swapped list: 1 0 3 2 5 4

您可以添加自己检查 malloc(s) 是否成功。

可以使用 struct Node ** 类型的变量 list 编写更安全的程序。

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

struct Node
{
    int data;
    struct Node *next; 
};

int main(void) 
{
    const int N = 6;
    struct Node *head;
    struct Node **list;

    list = &head;

    for ( int i = 0; ( i < N ) && ( *list = ( struct Node *)malloc( sizeof( struct Node ) ) ); i++ )
    {
        if ( *list )
        {
            ( *list )->data = i;
            list = &( *list )->next;
        }
    }

    *list = NULL;

    printf("Original list: ");
    for ( list = &head; *list; list = &( *list )->next )
    {
        printf( "%d ", ( *list )->data );
    }
    putchar( '\n' );

    list = &head;

    while ( *list && ( *list )->next )
    {
        int temp = ( *list )->data;
        ( *list )->data = ( *list )->next->data;
        ( *list )->next->data = temp;
        list = &( *list )->next->next;
    }

    printf("Pair swapped list: ");
    for ( list = &head; *list; list = &( *list )->next )
    {
        printf( "%d ", ( *list )->data );
    }
    putchar( '\n' );

    return 0;
}

考虑到您应该为列表释放所有分配的内存。

还有一件事。该程序不交换节点。它交换相邻节点的数据成员 data 的值。:)