📜  以给定大小的组反转双向链表

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

以给定大小的组反转双向链表

给定一个包含n 个节点的双向链表。问题是反转列表中的每组k 个节点。

例子:

先决条件:反转双向链表 |设置-2。
方法:创建一个递归函数say reverse(head, k) 。该函数接收每组k 个节点的头部或第一个节点。它通过应用反向双向链表 | 中讨论的方法来反向那些k 个节点组。设置-2。在反转k 个节点组后,该函数检查列表中是否存在下一组节点。如果组存在,则它使用下一组的第一个节点对自身进行递归调用,并对该组的下一个和上一个链接进行必要的调整。最后它返回反向组的新头节点。

C++
// C++ implementation to reverse a doubly linked list
// in groups of given size
#include 
  
using namespace std;
  
// a node of the doubly linked list
struct Node {
    int data;
    Node *next, *prev;
};
  
// function to get a new node
Node* getNode(int data)
{
    // allocate space
    Node* new_node = (Node*)malloc(sizeof(Node));
  
    // put in the data
    new_node->data = data;
    new_node->next = new_node->prev = NULL;
    return new_node;
}
  
// function to insert a node at the beginging
// of the Doubly Linked List
void push(Node** head_ref, Node* new_node)
{
    // since we are adding at the beginning,
    // prev is always NULL
    new_node->prev = NULL;
  
    // link the old list off the new node
    new_node->next = (*head_ref);
  
    // change prev of head node to new node
    if ((*head_ref) != NULL)
        (*head_ref)->prev = new_node;
  
    // move the head to point to the new node
    (*head_ref) = new_node;
}
 
// function to reverse a doubly linked list
// in groups of given size
Node* revListInGroupOfGivenSize(Node* head, int k)
{
    Node *current = head;
    Node* next = NULL;
    Node* newHead = NULL;
    int count = 0;
     
    // reversing the current group of k
    // or less than k nodes by adding
    // them at the beginning of list
    // 'newHead'
    while (current != NULL && count < k)
    {
        next = current->next;
        push(&newHead, current);
        current = next;
        count++;
    }
     
    // if next group exists then making the desired
    // adjustments in the link
    if (next != NULL)
    {
        head->next = revListInGroupOfGivenSize(next, k);
        head->next->prev = head;
    }
     
    // pointer to the new head of the
    // reversed group
    return newHead;
}
 
// Function to print nodes in a
// given doubly linked list
void printList(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
}
  
// Driver program to test above
int main()
{
    // Start with the empty list
    Node* head = NULL;
  
    // Create doubly linked: 10<->8<->4<->2
    push(&head, getNode(2));
    push(&head, getNode(4));
    push(&head, getNode(8));
    push(&head, getNode(10));
     
    int k = 2;
  
    cout << "Original list: ";
    printList(head);
  
    // Reverse doubly linked list in groups of
    // size 'k'
    head = revListInGroupOfGivenSize(head, k);
  
    cout << "\nModified list: ";
    printList(head);
  
    return 0;
}


Java
// Java implementation to reverse a doubly linked list
// in groups of given size
import java.io.*;
import java.util.*;
 
// Represents a node of doubly linked list
class Node
{
    int data;
    Node next, prev;
}
 
class GFG
{
 
    // function to get a new node
    static Node getNode(int data)
    {
        // allocating node
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = new_node.prev = null;
 
        return new_node;
    }
 
    // function to insert a node at the beginning
    // of the Doubly Linked List
    static Node push(Node head, Node new_node)
    {
        // since we are adding at the beginning,
        // prev is always NULL
        new_node.prev = null;
 
        // link the old list off the new node
        new_node.next = head;
 
        // change prev of head node to new node
        if (head != null)
            head.prev = new_node;
 
        // move the head to point to the new node
        head = new_node;
        return head;
    }
 
    // function to reverse a doubly linked list
    // in groups of given size
    static Node revListInGroupOfGivenSize(Node head, int k)
    {
        Node current = head;
        Node next = null;
        Node newHead = null;
        int count = 0;
 
        // reversing the current group of k
        // or less than k nodes by adding
        // them at the beginning of list
        // 'newHead'
        while (current != null && count < k)
        {
            next = current.next;
            newHead = push(newHead, current);
            current = next;
            count++;
        }
 
        // if next group exists then making the desired
        // adjustments in the link
        if (next != null)
        {
            head.next = revListInGroupOfGivenSize(next, k);
            head.next.prev = head;
        }
 
        // pointer to the new head of the
        // reversed group
        return newHead;
    }
 
    // Function to print nodes in a
    // given doubly linked list
    static void printList(Node head)
    {
        while (head != null)
        {
            System.out.print(head.data + " ");
            head = head.next;
        }
    }
 
    // Driver code
    public static void main(String args[])
    {
        // Start with the empty list
        Node head = null;
             
        // Create doubly linked: 10<->8<->4<->2
        head = push(head, getNode(2));
        head = push(head, getNode(4));
        head = push(head, getNode(8));
        head = push(head, getNode(10));
 
        int k = 2;
             
        System.out.print("Original list: ");
        printList(head);
 
        // Reverse doubly linked list in groups of
        // size 'k'
        head = revListInGroupOfGivenSize(head, k);
 
        System.out.print("\nModified list: ");
        printList(head);
    }
}
 
// This code is contributed by rachana soma


Python
# Python implementation to reverse a doubly linked list
# in groups of given size
 
# Link list node
class Node:
     
    def __init__(self, data):
        self.data = data
        self.next = next
         
# function to get a new node
def getNode(data):
 
    # allocate space
    new_node = Node(0)
 
    # put in the data
    new_node.data = data
    new_node.next = new_node.prev = None
    return new_node
 
# function to insert a node at the beginging
# of the Doubly Linked List
def push(head_ref, new_node):
 
    # since we are adding at the beginning,
    # prev is always None
    new_node.prev = None
 
    # link the old list off the new node
    new_node.next = (head_ref)
 
    # change prev of head node to new node
    if ((head_ref) != None):
        (head_ref).prev = new_node
 
    # move the head to point to the new node
    (head_ref) = new_node
    return head_ref
 
# function to reverse a doubly linked list
# in groups of given size
def revListInGroupOfGivenSize( head, k):
 
    current = head
    next = None
    newHead = None
    count = 0
     
    # reversing the current group of k
    # or less than k nodes by adding
    # them at the beginning of list
    # 'newHead'
    while (current != None and count < k):
     
        next = current.next
        newHead = push(newHead, current)
        current = next
        count = count + 1
     
    # if next group exists then making the desired
    # adjustments in the link
    if (next != None):
     
        head.next = revListInGroupOfGivenSize(next, k)
        head.next.prev = head
     
    # pointer to the new head of the
    # reversed group
    return newHead
 
# Function to print nodes in a
# given doubly linked list
def printList(head):
 
    while (head != None):
        print( head.data , end=" ")
        head = head.next
     
# Driver program to test above
 
# Start with the empty list
head = None
 
# Create doubly linked: 10<.8<.4<.2
head = push(head, getNode(2))
head = push(head, getNode(4))
head = push(head, getNode(8))
head = push(head, getNode(10))
     
k = 2
 
print("Original list: ")
printList(head)
 
# Reverse doubly linked list in groups of
# size 'k'
head = revListInGroupOfGivenSize(head, k)
 
print("\nModified list: ")
printList(head)
 
# This code is contributed by Arnab Kundu


C#
// C# implementation to reverse a doubly linked list
// in groups of given size
using System;
 
// Represents a node of doubly linked list
public class Node
{
    public int data;
    public Node next, prev;
}
 
class GFG
{
 
    // function to get a new node
    static Node getNode(int data)
    {
        // allocating node
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = new_node.prev = null;
 
        return new_node;
    }
 
    // function to insert a node at the beginning
    // of the Doubly Linked List
    static Node push(Node head, Node new_node)
    {
        // since we are adding at the beginning,
        // prev is always NULL
        new_node.prev = null;
 
        // link the old list off the new node
        new_node.next = head;
 
        // change prev of head node to new node
        if (head != null)
            head.prev = new_node;
 
        // move the head to point to the new node
        head = new_node;
        return head;
    }
 
    // function to reverse a doubly linked list
    // in groups of given size
    static Node revListInGroupOfGivenSize(Node head, int k)
    {
        Node current = head;
        Node next = null;
        Node newHead = null;
        int count = 0;
 
        // reversing the current group of k
        // or less than k nodes by adding
        // them at the beginning of list
        // 'newHead'
        while (current != null && count < k)
        {
            next = current.next;
            newHead = push(newHead, current);
            current = next;
            count++;
        }
 
        // if next group exists then making the desired
        // adjustments in the link
        if (next != null)
        {
            head.next = revListInGroupOfGivenSize(next, k);
            head.next.prev = head;
        }
 
        // pointer to the new head of the
        // reversed group
        return newHead;
    }
 
    // Function to print nodes in a
    // given doubly linked list
    static void printList(Node head)
    {
        while (head != null)
        {
            Console.Write(head.data + " ");
            head = head.next;
        }
    }
 
    // Driver code
    public static void Main(String []args)
    {
        // Start with the empty list
        Node head = null;
             
        // Create doubly linked: 10<->8<->4<->2
        head = push(head, getNode(2));
        head = push(head, getNode(4));
        head = push(head, getNode(8));
        head = push(head, getNode(10));
 
        int k = 2;
             
        Console.Write("Original list: ");
        printList(head);
 
        // Reverse doubly linked list in groups of
        // size 'k'
        head = revListInGroupOfGivenSize(head, k);
 
        Console.Write("\nModified list: ");
        printList(head);
    }
}
 
// This code is contributed by Arnab Kundu


Javascript


C++
#include 
using namespace std;
struct Node {
    int data;
    Node *next, *prev;
};
// function to add Node at the end of a Doubly LinkedList
Node* insertAtEnd(Node* head, int data)
{
 
    Node* new_node = new Node();
    new_node->data = data;
    new_node->next = NULL;
    Node* temp = head;
    if (head == NULL) {
        new_node->prev = NULL;
        head = new_node;
        return head;
    }
 
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = new_node;
    new_node->prev = temp;
    return head;
}
// function to print Doubly LinkedList
void printDLL(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}
// function to Reverse a doubly linked list
// in groups of given size
Node* reverseByN(Node* head, int k)
{
    if (!head)
        return NULL;
    head->prev = NULL;
    Node *temp, *curr = head, *newHead;
    int count = 0;
    while (curr != NULL && count < k) {
        newHead = curr;
        temp = curr->prev;
        curr->prev = curr->next;
        curr->next = temp;
        curr = curr->prev;
        count++;
    }
    // checking if the reversed LinkedList size is
    // equal to K or not
    // if it is not equal to k that means we have reversed
    // the last set of size K and we don't need to call the
    // recursive function
    if (count >= k) {
        Node* rest = reverseByN(curr, k);
        head->next = rest;
        if (rest != NULL)
            // it is required for prev link otherwise u wont
            // be backtrack list due to broken links
            rest->prev = head;
    }
    return newHead;
}
int main()
{
    Node* head;
    for (int i = 1; i <= 10; i++) {
        head = insertAtEnd(head, i);
    }
    printDLL(head);
    int n = 4;
    head = reverseByN(head, n);
    printDLL(head);
}


Java
import java.io.*;
 
class Node {
    int data;
    Node next, prev;
}
 
class GFG {
 
    // Function to add Node at the end of a
    // Doubly LinkedList
    static Node insertAtEnd(Node head, int data)
    {
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = null;
        Node temp = head;
 
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return head;
        }
 
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = new_node;
        new_node.prev = temp;
        return head;
    }
 
    // Function to print Doubly LinkedList
    static void printDLL(Node head)
    {
        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
        System.out.println();
    }
 
    // Function to Reverse a doubly linked list
    // in groups of given size
    static Node reverseByN(Node head, int k)
    {
        if (head == null)
            return null;
 
        head.prev = null;
        Node temp;
        Node curr = head;
        Node newHead = null;
        int count = 0;
 
        while (curr != null && count < k) {
            newHead = curr;
            temp = curr.prev;
            curr.prev = curr.next;
            curr.next = temp;
            curr = curr.prev;
            count++;
        }
 
        // Checking if the reversed LinkedList size is
        // equal to K or not. If it is not equal to k
        // that means we have reversed the last set of
        // size K and we don't need to call the
        // recursive function
        if (count >= k) {
            Node rest = reverseByN(curr, k);
            head.next = rest;
            if (rest != null)
                // it is required for prev link otherwise u
                // wont be backtrack list due to broken
                // links
                rest.prev = head;
        }
        return newHead;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Node head = null;
        for (int i = 1; i <= 10; i++) {
            head = insertAtEnd(head, i);
        }
 
        printDLL(head);
        int n = 4;
 
        head = reverseByN(head, n);
        printDLL(head);
    }
}
 
// This code is contributed by avanitrachhadiya2155


Javascript


输出

Original list: 10 8 4 2 
Modified list: 8 10 2 4 

时间复杂度: O(n)。

我们可以使用相同的思想进一步简化该算法的实现,只需在一个函数进行递归。

C++

#include 
using namespace std;
struct Node {
    int data;
    Node *next, *prev;
};
// function to add Node at the end of a Doubly LinkedList
Node* insertAtEnd(Node* head, int data)
{
 
    Node* new_node = new Node();
    new_node->data = data;
    new_node->next = NULL;
    Node* temp = head;
    if (head == NULL) {
        new_node->prev = NULL;
        head = new_node;
        return head;
    }
 
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = new_node;
    new_node->prev = temp;
    return head;
}
// function to print Doubly LinkedList
void printDLL(Node* head)
{
    while (head != NULL) {
        cout << head->data << " ";
        head = head->next;
    }
    cout << endl;
}
// function to Reverse a doubly linked list
// in groups of given size
Node* reverseByN(Node* head, int k)
{
    if (!head)
        return NULL;
    head->prev = NULL;
    Node *temp, *curr = head, *newHead;
    int count = 0;
    while (curr != NULL && count < k) {
        newHead = curr;
        temp = curr->prev;
        curr->prev = curr->next;
        curr->next = temp;
        curr = curr->prev;
        count++;
    }
    // checking if the reversed LinkedList size is
    // equal to K or not
    // if it is not equal to k that means we have reversed
    // the last set of size K and we don't need to call the
    // recursive function
    if (count >= k) {
        Node* rest = reverseByN(curr, k);
        head->next = rest;
        if (rest != NULL)
            // it is required for prev link otherwise u wont
            // be backtrack list due to broken links
            rest->prev = head;
    }
    return newHead;
}
int main()
{
    Node* head;
    for (int i = 1; i <= 10; i++) {
        head = insertAtEnd(head, i);
    }
    printDLL(head);
    int n = 4;
    head = reverseByN(head, n);
    printDLL(head);
}

Java

import java.io.*;
 
class Node {
    int data;
    Node next, prev;
}
 
class GFG {
 
    // Function to add Node at the end of a
    // Doubly LinkedList
    static Node insertAtEnd(Node head, int data)
    {
        Node new_node = new Node();
        new_node.data = data;
        new_node.next = null;
        Node temp = head;
 
        if (head == null) {
            new_node.prev = null;
            head = new_node;
            return head;
        }
 
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = new_node;
        new_node.prev = temp;
        return head;
    }
 
    // Function to print Doubly LinkedList
    static void printDLL(Node head)
    {
        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
        System.out.println();
    }
 
    // Function to Reverse a doubly linked list
    // in groups of given size
    static Node reverseByN(Node head, int k)
    {
        if (head == null)
            return null;
 
        head.prev = null;
        Node temp;
        Node curr = head;
        Node newHead = null;
        int count = 0;
 
        while (curr != null && count < k) {
            newHead = curr;
            temp = curr.prev;
            curr.prev = curr.next;
            curr.next = temp;
            curr = curr.prev;
            count++;
        }
 
        // Checking if the reversed LinkedList size is
        // equal to K or not. If it is not equal to k
        // that means we have reversed the last set of
        // size K and we don't need to call the
        // recursive function
        if (count >= k) {
            Node rest = reverseByN(curr, k);
            head.next = rest;
            if (rest != null)
                // it is required for prev link otherwise u
                // wont be backtrack list due to broken
                // links
                rest.prev = head;
        }
        return newHead;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        Node head = null;
        for (int i = 1; i <= 10; i++) {
            head = insertAtEnd(head, i);
        }
 
        printDLL(head);
        int n = 4;
 
        head = reverseByN(head, n);
        printDLL(head);
    }
}
 
// This code is contributed by avanitrachhadiya2155

Javascript


输出
1 2 3 4 5 6 7 8 9 10 
4 3 2 1 8 7 6 5 10 9 

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