📜  交替合并前半部分和反转链表的后半部分

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

交替合并前半部分和反转链表的后半部分

给定一个链表,任务是按以下方式重新排列链表:

  1. 反转给定链表的后半部分。
    • 链表的第一个元素是前半部分的第一个元素。
    • 链表的第二个元素是后半部分的第一个元素。

例子:

Input: 1->2->3->4->5
Output: 1->5->2->4->3

Input: 1->2->3->4->5->6
Output: 1->6->2->5->3->4

方法:首先找到链表的中间节点。该方法已在此处讨论。将链表从中间反转到最后。一旦链表反转,从头开始遍历,同时从链表的前半部分插入一个节点,并从链表的后半部分插入另一个节点。继续这个过程,直到到达中间节点。到达中间节点后,将中间节点之前的节点指向 NULL。
下面是上述方法的实现:

C++
// C++ program to sandwich the last part of
// linked list in between the first part of
// the linked list
#include
#include 
using namespace std;
 
struct node {
    int data;
    struct node* next;
};
  
// Function to reverse Linked List
struct node* reverseLL(struct node* root)
{
    struct node *prev = NULL, *current = root, *next;
    while (current) {
        next = current->next;
        current->next = prev;
        prev = current;
        current = next;
    }
  
    // root needs to be updated after reversing
    root = prev;
    return root;
}
  
// Function to modify Linked List
void modifyLL(struct node* root)
{
    // Find the mid node
    struct node *slow_ptr = root, *fast_ptr = root;
    while (fast_ptr && fast_ptr->next) {
        fast_ptr = fast_ptr->next->next;
        slow_ptr = slow_ptr->next;
    }
  
    // Reverse the second half of the list
    struct node* root2 = reverseLL(slow_ptr->next);
  
    // partition the list
    slow_ptr->next = NULL;
  
    struct node *current1 = root, *current2 = root2;
  
    // insert the elements in between
    while (current1 && current2) {
  
        // next node to be traversed in the first list
        struct node* dnext1 = current1->next;
  
        // next node to be traversed in the first list
        struct node* dnext2 = current2->next;
        current1->next = current2;
        current2->next = dnext1;
        current1 = dnext1;
        current2 = dnext2;
    }
}
  
// Function to insert node after the end
void insertNode(struct node** start, int val)
{
  
    // allocate memory
    struct node* temp = (struct node*)malloc(sizeof(struct node));
    temp->data = val;
  
    // if first node
    if (*start == NULL)
        *start = temp;
    else {
  
        // move to the end pointer of node
        struct node* dstart = *start;
        while (dstart->next != NULL)
            dstart = dstart->next;
        dstart->next = temp;
    }
}
  
// function to print the linked list
void display(struct node** start)
{
    struct node* temp = *start;
  
    // traverse till the entire linked
    // list is printed
    while (temp->next != NULL) {
        printf("%d->", temp->data);
        temp = temp->next;
    }
    printf("%d\n", temp->data);
}
  
// Driver Code
int main()
{
    // Odd Length Linked List
    struct node* start = NULL;
    insertNode(&start, 1);
    insertNode(&start, 2);
    insertNode(&start, 3);
    insertNode(&start, 4);
    insertNode(&start, 5);
  
    printf("Before Modifying: ");
    display(&start);
    modifyLL(start);
    printf("After Modifying: ");
    display(&start);
  
    // Even Length Linked List
    start = NULL;
    insertNode(&start, 1);
    insertNode(&start, 2);
    insertNode(&start, 3);
    insertNode(&start, 4);
    insertNode(&start, 5);
    insertNode(&start, 6);
  
    printf("\nBefore Modifying: ");
    display(&start);
    modifyLL(start);
    printf("After Modifying: ");
    display(&start);
  
    return 0;
}


Java
// Java program to sandwich the
// last part of linked list in
// between the first part of
// the linked list
import java.util.*;
 
class node
{
    int data;
    node next;
    node(int key)
    {
        data = key;
        next = null;
    }
}
 
class GFG
{
     
// Function to reverse
// Linked List
public static node reverseLL(node root)
{
     
     node prev = null,
     current = root, next;
    while (current!= null)
    {
        next = current.next;
        current.next = prev;
        prev = current;
        current = next;
    }
 
    // root needs to be
    // updated after reversing
    root = prev;
    return root;
}
 
// Function to modify
// Linked List
public static void modifyLL( node root)
{
    // Find the mid node
     node slow_ptr = root, fast_ptr = root;
    while (fast_ptr != null &&
           fast_ptr.next != null)
    {
        fast_ptr = fast_ptr.next.next;
        slow_ptr = slow_ptr.next;
    }
 
    // Reverse the second
    // half of the list
    node root2 = reverseLL(slow_ptr.next);
 
    // partition the list
    slow_ptr.next = null;
 
     node current1 = root,
          current2 = root2;
 
    // insert the elements in between
    while (current1 != null &&
           current2 != null)
    {
 
        // next node to be traversed
        // in the first list
        node dnext1 = current1.next;
 
        // next node to be traversed
        // in the first list
        node dnext2 = current2.next;
        current1.next = current2;
        current2.next = dnext1;
        current1 = dnext1;
        current2 = dnext2;
    }
}
 
// Function to insert
// node after the end
public static node insertNode(node start,
                              int val)
{
 
    // allocate memory
    node temp = new node(val);
 
    // if first node
    if (start == null)
        start = temp;
    else
    {
 
        // move to the end
        // pointer of node
         node dstart = start;
        while (dstart.next != null)
            dstart = dstart.next;
        dstart.next = temp;
    }
     
    return start;
}
 
// function to print
// the linked list
public static void display(node start)
{
     node temp = start;
 
    // traverse till the
    // entire linked
    // list is printed
    while (temp.next != null) {
        System.out.print(temp.data + "->");
        temp = temp.next;
    }
    System.out.println(temp.data);
}
 
// Driver Code
public static void main(String args[])
{
    // Odd Length Linked List
    node start = null;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
 
    System.out.print("Before Modifying: ");
    display(start);
    modifyLL(start);
    System.out.print("After Modifying: ");
    display(start);
 
    // Even Length Linked List
    start = null;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
    start = insertNode(start, 6);
 
 
    System.out.print("Before Modifying: ");
    display(start);
    modifyLL(start);
    System.out.print("After Modifying: ");
    display(start);
}
}


Python3
# Python3 program to sandwich the last part of
# linked list in between the first part of
# the linked list
class node:   
    def __init__(self):     
        self.data = 0
        self.next = None
  
# Function to reverse Linked List
def reverseLL(root):
    prev = None
    current = root  
    while (current):
        next = current.next;
        current.next = prev;
        prev = current;
        current = next;
   
    # root needs to be updated after reversing
    root = prev;
    return root;
   
# Function to modify Linked List
def modifyLL(root):
 
    # Find the mid node
    slow_ptr = root
    fast_ptr = root;
    while (fast_ptr and fast_ptr.next):
        fast_ptr = fast_ptr.next.next;
        slow_ptr = slow_ptr.next;
   
    # Reverse the second half of the list
    root2 = reverseLL(slow_ptr.next);
   
    # partition the list
    slow_ptr.next = None; 
    current1 = root
    current2 = root2;
   
    # insert the elements in between
    while (current1 and current2):
   
        # next node to be traversed in the first list
        dnext1 = current1.next;
   
        # next node to be traversed in the first list
        dnext2 = current2.next;
        current1.next = current2;
        current2.next = dnext1;
        current1 = dnext1;
        current2 = dnext2;
       
# Function to insert node after the end
def insertNode(start, val):
   
    # allocate memory
    temp = node()
    temp.data = val;
   
    # if first node
    if (start == None):
        start = temp;
    else:
   
        # move to the end pointer of node
        dstart = start;
        while (dstart.next != None):
            dstart = dstart.next;
        dstart.next = temp;
    return start
     
# function to print the linked list
def display(start):
    temp = start;
   
    # traverse till the entire linked
    # list is printed
    while (temp.next != None):
        print("{}->".format(temp.data), end = '')
        temp = temp.next;   
    print("{}".format(temp.data))
 
# Driver Code
if __name__=='__main__':
     
    # Odd Length Linked List
    start = None;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
   
    print("Before Modifying: ", end = '');
    display(start);
    modifyLL(start);
    print("After Modifying: ", end = '');
    display(start);
   
    # Even Length Linked List
    start = None;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
    start = insertNode(start, 6);
   
    print("\nBefore Modifying: ", end = '');
    display(start);
    modifyLL(start);
    print("After Modifying: ", end = '')
    display(start);
 
# This code is contributed by rutvik_56


C#
// C# program to sandwich the last part
// of linked list in between the first
// part of the linked list
using System;
 
public class node
{
    public int data;
    public node next;
    public node(int key)
    {
        data = key;
        next = null;
    }
}
 
public class GFG
{
     
// Function to reverse
// Linked List
public static node reverseLL(node root)
{
    node prev = null,
    current = root, next;
    while (current!= null)
    {
        next = current.next;
        current.next = prev;
        prev = current;
        current = next;
    }
 
    // root needs to be
    // updated after reversing
    root = prev;
    return root;
}
 
// Function to modify
// Linked List
public static void modifyLL( node root)
{
    // Find the mid node
    node slow_ptr = root, fast_ptr = root;
    while (fast_ptr != null &&
           fast_ptr.next != null)
    {
        fast_ptr = fast_ptr.next.next;
        slow_ptr = slow_ptr.next;
    }
 
    // Reverse the second
    // half of the list
    node root2 = reverseLL(slow_ptr.next);
 
    // partition the list
    slow_ptr.next = null;
 
    node current1 = root,
        current2 = root2;
 
    // insert the elements in between
    while (current1 != null &&
           current2 != null)
    {
 
        // next node to be traversed
        // in the first list
        node dnext1 = current1.next;
 
        // next node to be traversed
        // in the first list
        node dnext2 = current2.next;
        current1.next = current2;
        current2.next = dnext1;
        current1 = dnext1;
        current2 = dnext2;
    }
}
 
// Function to insert
// node after the end
public static node insertNode(node start,
                               int val)
{
 
    // allocate memory
    node temp = new node(val);
 
    // if first node
    if (start == null)
        start = temp;
    else
    {
 
        // move to the end
        // pointer of node
        node dstart = start;
        while (dstart.next != null)
            dstart = dstart.next;
        dstart.next = temp;
    }
     
    return start;
}
 
// function to print
// the linked list
public static void display(node start)
{
    node temp = start;
 
    // traverse till the
    // entire linked
    // list is printed
    while (temp.next != null)
    {
        Console.Write(temp.data + "->");
        temp = temp.next;
    }
    Console.WriteLine(temp.data);
}
 
// Driver Code
public static void Main(String []args)
{
    // Odd Length Linked List
    node start = null;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
 
    Console.Write("Before Modifying: ");
    display(start);
    modifyLL(start);
    Console.Write("After Modifying: ");
    display(start);
 
    // Even Length Linked List
    start = null;
    start = insertNode(start, 1);
    start = insertNode(start, 2);
    start = insertNode(start, 3);
    start = insertNode(start, 4);
    start = insertNode(start, 5);
    start = insertNode(start, 6);
 
    Console.Write("Before Modifying: ");
    display(start);
    modifyLL(start);
    Console.Write("After Modifying: ");
    display(start);
}
}
 
// This code has been contributed
// by 29AjayKumar


Javascript


输出:

Before Modifying: 1->2->3->4->5
After Modifying: 1->5->2->4->3

Before Modifying: 1->2->3->4->5->6
After Modifying: 1->6->2->5->3->4

时间复杂度: O(N)
练习:在不从中间节点反转链表的情况下解决问题。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程