【问题标题】:Given linked list pairs swap by changing links给定链表对通过更改链接进行交换
【发布时间】:2020-11-14 08:50:11
【问题描述】:

我有一个单链表,其中我得到了struct Node* head,返回值为void。我想成对交换而不复制数据。

例如,如果输入为2->4->6,则输出为4->2->6。但如果输入为2->4->6->7,则输出为4->2->7->6

这是我的代码,但它不起作用。

void swapPairs(struct Node *head) {
    struct Node *node;
    while (head && head->next) {
        struct Node *nxt = head->next;
        head->next = nxt->next;
        nxt->next = head;
        node->next = nxt;
        node = head;
        head = node->next;
    }
}

【问题讨论】:

  • swapPairs() 的参数必须是 struct Node **head 或者您必须将返回类型从 void 更改为 struct Node * 以便您可以返回新的头节点以分配给原始列表指针调用者。

标签: c linked-list swap singly-linked-list function-definition


【解决方案1】:

您需要通过引用将指针传递给头(或当前)节点。否则,该函数将处理传递的指针值的副本。更改副本不会影响原始指针。

这是一个演示程序,展示了如何编写交换相邻节点的函数。

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

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

struct Node *insert( struct Node *head, size_t pos, int data )
{
    if (head == NULL || pos == 0)
    {
        struct Node *new_node = ( struct Node * )malloc( sizeof( struct Node ) );
        new_node->next = head;
        new_node->data = data;
        head = new_node;
    }
    else
    {
        head->next = insert( head->next, pos - 1, data );
    }

    return head;
}

 FILE * display( const struct Node *head, FILE *fp )
{
    for ( ; head != NULL; head = head->next )
    {
        fprintf( fp, "%d -> ", head->data );
    }
    fputs( "null\n", fp );

    return fp;
}

void swap( struct Node **current )
{
/*
    | A | -> | A | B | -> | B | C |
    head

    Step 1:
    | B |    | A | C |  | B | C |
    head

    Step 2:
    | B |   | A | C |   | B | A |
    head
*/

    //  Step 1:
    struct Node *tmp = *current;
    *current = ( *current )->next;
    tmp->next = ( *current )->next;

    //  Step 2:
    ( *current )->next = tmp;
}

void swapPairs( struct Node **head )
{
    for ( ; *head && ( *head )->next; head = &( *head )->next->next)
    {
        swap( head );
    }
}

int main()
{
    struct Node *head = NULL;
    const int N = 10;

    srand( ( unsigned int )time( NULL ) );
    for ( int i = 0; i < N; i++ )
    {
        head = insert( head, rand() %( i + 1 ), rand() % N );
    }
        
    fputc( '\n', display( head, stdout ) );

    swapPairs( &head );    

    fputc( '\n', display( head, stdout ) );
}

程序输出可能看起来像

4 -> 7 -> 8 -> 1 -> 4 -> 8 -> 9 -> 0 -> 4 -> 6 -> null

7 -> 4 -> 1 -> 8 -> 8 -> 4 -> 0 -> 9 -> 6 -> 4 -> null

【讨论】:

  • 感谢您的快速回答,但主要问题是我如何只得到“struct Node *head”,而不是 **head..:/
  • @AnonymusfromUSA 如果函数的返回类型为 void,则不能执行此操作。否则需要将返回类型改为struct Node *,函数体会更复杂。
  • @AnonymusfromUSA 如果你想交换一些东西,你必须通过引用传递它,这是一种通用方法。
  • @AnonymusfromUSA 这不是main() 中声明的head 的类型,它是swapPairs() 的参数类型,必须是Node**。为什么?当你将一个指针(例如Node*)传递给一个函数时,函数会接收到一个指针的副本,该指针具有它自己且非常不同的地址(它与它的值保持相同的地址),但指针地址本身不是与main()中的指针地址相同。因此,您对作为 Node* 传递的指针所做的任何更改都会在函数返回时丢失。使用Node**,您可以对来自main() 的相同指针地址进行操作——这允许您交换head
猜你喜欢
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 2014-01-17
  • 1970-01-01
相关资源
最近更新 更多