交替合并前半部分和反转链表的后半部分
给定一个链表,任务是按以下方式重新排列链表:
- 反转给定链表的后半部分。
- 链表的第一个元素是前半部分的第一个元素。
- 链表的第二个元素是后半部分的第一个元素。
例子:
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 现场工作专业课程和学生竞争性编程现场课程。