【问题标题】:What is wrong with my code for Pairwise swapping of linked list in C?我的 C 中链表成对交换的代码有什么问题?
【发布时间】:2018-08-06 22:11:03
【问题描述】:

这是我的配对代码:

#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) 那么它会导致无限循环。如果代码保持不变,最后会创建一个垃圾元素。请帮帮我。

【问题讨论】:

  • 与崩溃无关,但你从未初始化list-&gt;data,它的值将是indeterminate且看似随机的。
  • 至于你的crash,请学习如何使用调试器,这样你就可以在监控变量和指针等的同时逐行执行代码。
  • 你没有free()你的记忆。并非所有操作系统都会在 main() 结束时回收 un-free()d 内存。
  • 你认为第一个循环中的list-&gt;data; 有什么作用,为什么会有那个代码?

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


【解决方案1】:

导致问题的行是:

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

list-&gt;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;
}

【讨论】:

  • 我提到的第二个问题呢?
  • @purplepsypcho 但不只是在循环工作后分配 list = NULL 吗?那不是为了同样的目的吗?
  • 好吧,我得到了一个更简单的解决方案,我只是将 ainext 不会在最后一次迭代中执行,额外的节点也不会已创建。
【解决方案2】:

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

您的while 检查list-&gt;next-&gt;next!=NULL,并在循环结束时移动list,如下所示:list = list-&gt;next-&gt;next;

这意味着你的循环运行于:

  • 第一个节点,与第二个交换
  • 第三个节点,与第四个交换
  • 第 5 个节点,与第 6 个交换。

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

(对于您应该做的事情,请遵从 Purplepsycho ——我不会从其他人的答案中复制。;-))

【讨论】:

  • 现在可以正常工作了。但是第二个问题呢。如何防止垃圾元素最后产生?
  • @Gameatro:你问题的第二部分不清楚。 list = NULL 应该实现什么?你说的是什么“垃圾”?
  • 在创建列表循环后,我将 list->next = NULL。它正在创建一个带有垃圾值的额外列表。但是如果我只写 list=NULL,而使用条件 while(list!=NULL) 打印时,它会进入无限循环。
【解决方案3】:

对于根据 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 是否成功。

可以使用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 的值。:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 2017-05-02
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多