📌  相关文章
📜  通过更改链接对给定链表的元素进行成对交换的 C 程序

📅  最后修改于: 2022-05-13 01:57:39.557000             🧑  作者: Mango

通过更改链接对给定链表的元素进行成对交换的 C 程序

给定一个单链表,编写一个函数来成对交换元素。例如,如果链表是 1->2->3->4->5->6->7,那么函数应该将其更改为 2->1->4->3->6->5 ->7,如果链表是 1->2->3->4->5->6,那么函数应该将其更改为 2->1->4->3->6->5

这个问题已经在这里讨论过了。那里提供的解决方案交换节点的数据。如果数据包含很多字段,就会有很多交换操作。因此,更改链接通常是一个更好的主意。以下是更改链接而不是交换数据的实现。

C
/* This program swaps the nodes of
   linked list rather than swapping
   the field from the nodes. Imagine
   a case where a node contains many
   fields, there will be plenty of
   unnecessary swap calls. */
 
#include 
#include 
#include 
 
// A linked list node
struct Node
{
    int data;
    struct Node* next;
};
 
/* Function to pairwise swap
   elements of a linked list */
void pairWiseSwap(struct Node** head)
{
    // If linked list is empty or there
    // is only one node in list
    if (*head == NULL ||
       (*head)->next == NULL)
        return;
 
    // Initialize previous and current
    // pointers
    struct Node* prev = *head;
    struct Node* curr = (*head)->next;
 
    // Change head before proceeding
    *head = curr;
 
    // Traverse the list
    while (true)
    {
        struct Node* next = curr->next;
 
        // Change next of current as
        // previous node
        curr->next = prev;
 
        // If next NULL or next is the
        // last node
        if (next == NULL ||
            next->next == NULL)
        {
            prev->next = next;
            break;
        }
 
        // Change next of previous to
        // next next
        prev->next = next->next;
 
        // Update previous and curr
        prev = next;
        curr = prev->next;
    }
}
 
/* Function to add a node at the
   beginning of Linked List */
void push(struct Node** head_ref,
          int new_data)
{
    // Allocate node
    struct Node* new_node =
          (struct Node*)malloc(sizeof(struct Node));
 
    // Put in the data 
    new_node->data = new_data;
 
    // Link the old list off the
    // new node
    new_node->next = (*head_ref);
 
    // Move the head to point to
    // the new node
    (*head_ref) = new_node;
}
 
/* Function to print nodes in a
   given linked list */
void printList(struct Node* node)
{
    while (node != NULL)
    {
        printf("%d ",
               node->data);
        node = node->next;
    }
}
 
// Driver code
int main()
{
    struct Node* start = NULL;
 
    /* The constructed linked list is:
       1->2->3->4->5->6->7 */
    push(&start, 7);
    push(&start, 6);
    push(&start, 5);
    push(&start, 4);
    push(&start, 3);
    push(&start, 2);
    push(&start, 1);
 
    printf("
    Linked list before calling  pairWiseSwap() ");
    printList(start);
 
    pairWiseSwap(&start);
 
    printf("
    Linked list after calling  pairWiseSwap() ");
    printList(start);
 
    getchar();
    return 0;
}


C
/* This program swaps the nodes of linked list
   rather than swapping the field from the nodes.
   Imagine a case where a node contains many
   fields, there will be plenty of unnecessary
   swap calls. */
 
#include 
#include 
#include 
 
// A linked list node
struct node
{
    int data;
    struct node* next;
};
 
/* Function to pairwise swap elements of
   a linked list. It returns head of the
   modified list, so return value of this
   node must be assigned */
struct node* pairWiseSwap(struct node* head)
{
    // Base Case: The list is empty or has
    // only one node
    if (head == NULL ||
        head->next == NULL)
        return head;
 
    // Store head of list after two nodes
    struct node* remaining =
           head->next->next;
 
    // Change head
    struct node* newhead = head->next;
 
    // Change next of second node
    head->next->next = head;
 
    // Recur for remaining list and change
    // next of head
    head->next = pairWiseSwap(remaining);
 
    // Return new head of modified list
    return newhead;
}
 
/* Function to add a node at the
   beginning of Linked List */
void push(struct node** head_ref,
          int new_data)
{
    // Allocate node
    struct node* new_node =
          (struct node*)malloc(sizeof(struct node));
 
    // Put in the data 
    new_node->data = new_data;
 
    // Link the old list off the
    // new node
    new_node->next = (*head_ref);
 
    // Move the head to point to
    // the new node
    (*head_ref) = new_node;
}
 
/* Function to print nodes in a
   given linked list */
void printList(struct node* node)
{
    while (node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
}
 
// Driver code
int main()
{
    struct node* start = NULL;
 
    /* The constructed linked list is:
        1->2->3->4->5->6->7 */
    push(&start, 7);
    push(&start, 6);
    push(&start, 5);
    push(&start, 4);
    push(&start, 3);
    push(&start, 2);
    push(&start, 1);
 
    printf("
    Linked list before calling  pairWiseSwap() ");
    printList(start);
 
    // NOTE THIS CHANGE
    start = pairWiseSwap(start);
 
    printf("
    Linked list after calling  pairWiseSwap() ");
    printList(start);
 
    return 0;
}


输出:

Linked list before calling  pairWiseSwap() 1 2 3 4 5 6 7
Linked list after calling  pairWiseSwap() 2 1 4 3 6 5 7

时间复杂度:上述程序的时间复杂度为 O(n),其中 n 是给定链表中的节点数。 while 循环遍历给定的链表。

辅助空间: O(1)

以下是相同方法的递归实现。我们更改前两个节点并重复剩余列表。感谢 geek 和 omer salem 提出这种方法。

C

/* This program swaps the nodes of linked list
   rather than swapping the field from the nodes.
   Imagine a case where a node contains many
   fields, there will be plenty of unnecessary
   swap calls. */
 
#include 
#include 
#include 
 
// A linked list node
struct node
{
    int data;
    struct node* next;
};
 
/* Function to pairwise swap elements of
   a linked list. It returns head of the
   modified list, so return value of this
   node must be assigned */
struct node* pairWiseSwap(struct node* head)
{
    // Base Case: The list is empty or has
    // only one node
    if (head == NULL ||
        head->next == NULL)
        return head;
 
    // Store head of list after two nodes
    struct node* remaining =
           head->next->next;
 
    // Change head
    struct node* newhead = head->next;
 
    // Change next of second node
    head->next->next = head;
 
    // Recur for remaining list and change
    // next of head
    head->next = pairWiseSwap(remaining);
 
    // Return new head of modified list
    return newhead;
}
 
/* Function to add a node at the
   beginning of Linked List */
void push(struct node** head_ref,
          int new_data)
{
    // Allocate node
    struct node* new_node =
          (struct node*)malloc(sizeof(struct node));
 
    // Put in the data 
    new_node->data = new_data;
 
    // Link the old list off the
    // new node
    new_node->next = (*head_ref);
 
    // Move the head to point to
    // the new node
    (*head_ref) = new_node;
}
 
/* Function to print nodes in a
   given linked list */
void printList(struct node* node)
{
    while (node != NULL)
    {
        printf("%d ", node->data);
        node = node->next;
    }
}
 
// Driver code
int main()
{
    struct node* start = NULL;
 
    /* The constructed linked list is:
        1->2->3->4->5->6->7 */
    push(&start, 7);
    push(&start, 6);
    push(&start, 5);
    push(&start, 4);
    push(&start, 3);
    push(&start, 2);
    push(&start, 1);
 
    printf("
    Linked list before calling  pairWiseSwap() ");
    printList(start);
 
    // NOTE THIS CHANGE
    start = pairWiseSwap(start);
 
    printf("
    Linked list after calling  pairWiseSwap() ");
    printList(start);
 
    return 0;
}

输出:

Linked list before calling  pairWiseSwap() 1 2 3 4 5 6 7
Linked list after calling  pairWiseSwap() 2 1 4 3 6 5 7

时间复杂度: O(n)

辅助空间: O(n)

请通过更改链接来参阅有关给定链接列表的成对交换元素的完整文章以获取更多详细信息!