将一个循环链表分成两半
Original Linked List
Result Linked List 1
Result Linked List 2
如果有奇数个节点,那么第一个列表应该包含一个额外的。
感谢 Geek4u 提出算法。
1)使用龟兔兔算法存储循环链表的mid和last指针。
2)将下半部分做成圆形。
3)把前半部分做成圆形。
4) 设置两个链表的头(或起始)指针。
在下面的实现中,如果给定的循环链表中有奇数节点,则第一个结果列表比第二个结果列表多 1 个节点。
C++
// Program to split a circular linked list
// into two halves
#include
using namespace std;
/* structure for a node */
class Node
{
public:
int data;
Node *next;
};
/* Function to split a list (starting with head)
into two lists. head1_ref and head2_ref are
references to head nodes of the two resultant
linked lists */
void splitList(Node *head, Node **head1_ref,
Node **head2_ref)
{
Node *slow_ptr = head;
Node *fast_ptr = head;
if(head == NULL)
return;
/* If there are odd nodes in the circular list then
fast_ptr->next becomes head and for even nodes
fast_ptr->next->next becomes head */
while(fast_ptr->next != head &&
fast_ptr->next->next != head)
{
fast_ptr = fast_ptr->next->next;
slow_ptr = slow_ptr->next;
}
/* If there are even elements in list
then move fast_ptr */
if(fast_ptr->next->next == head)
fast_ptr = fast_ptr->next;
/* Set the head pointer of first half */
*head1_ref = head;
/* Set the head pointer of second half */
if(head->next != head)
*head2_ref = slow_ptr->next;
/* Make second half circular */
fast_ptr->next = slow_ptr->next;
/* Make first half circular */
slow_ptr->next = head;
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at
the beginning of a Circular linked list */
void push(Node **head_ref, int data)
{
Node *ptr1 = new Node();
Node *temp = *head_ref;
ptr1->data = data;
ptr1->next = *head_ref;
/* If linked list is not NULL then
set the next of last node */
if(*head_ref != NULL)
{
while(temp->next != *head_ref)
temp = temp->next;
temp->next = ptr1;
}
else
ptr1->next = ptr1; /*For the first node */
*head_ref = ptr1;
}
/* Function to print nodes in
a given Circular linked list */
void printList(Node *head)
{
Node *temp = head;
if(head != NULL)
{
cout << endl;
do {
cout << temp->data << " ";
temp = temp->next;
} while(temp != head);
}
}
// Driver Code
int main()
{
int list_size, i;
/* Initialize lists as empty */
Node *head = NULL;
Node *head1 = NULL;
Node *head2 = NULL;
/* Created linked list will be 12->56->2->11 */
push(&head, 12);
push(&head, 56);
push(&head, 2);
push(&head, 11);
cout << "Original Circular Linked List";
printList(head);
/* Split the list */
splitList(head, &head1, &head2);
cout << "\nFirst Circular Linked List";
printList(head1);
cout << "\nSecond Circular Linked List";
printList(head2);
return 0;
}
// This code is contributed by rathbhupendra
C
/* Program to split a circular linked list into two halves */
#include
#include
/* structure for a node */
struct Node
{
int data;
struct Node *next;
};
/* Function to split a list (starting with head) into two lists.
head1_ref and head2_ref are references to head nodes of
the two resultant linked lists */
void splitList(struct Node *head, struct Node **head1_ref,
struct Node **head2_ref)
{
struct Node *slow_ptr = head;
struct Node *fast_ptr = head;
if(head == NULL)
return;
/* If there are odd nodes in the circular list then
fast_ptr->next becomes head and for even nodes
fast_ptr->next->next becomes head */
while(fast_ptr->next != head &&
fast_ptr->next->next != head)
{
fast_ptr = fast_ptr->next->next;
slow_ptr = slow_ptr->next;
}
/* If there are even elements in list then move fast_ptr */
if(fast_ptr->next->next == head)
fast_ptr = fast_ptr->next;
/* Set the head pointer of first half */
*head1_ref = head;
/* Set the head pointer of second half */
if(head->next != head)
*head2_ref = slow_ptr->next;
/* Make second half circular */
fast_ptr->next = slow_ptr->next;
/* Make first half circular */
slow_ptr->next = head;
}
/* UTILITY FUNCTIONS */
/* Function to insert a node at the beginning of a Circular
linked list */
void push(struct Node **head_ref, int data)
{
struct Node *ptr1 = (struct Node *)malloc(sizeof(struct Node));
struct Node *temp = *head_ref;
ptr1->data = data;
ptr1->next = *head_ref;
/* If linked list is not NULL then set the next of
last node */
if(*head_ref != NULL)
{
while(temp->next != *head_ref)
temp = temp->next;
temp->next = ptr1;
}
else
ptr1->next = ptr1; /*For the first node */
*head_ref = ptr1;
}
/* Function to print nodes in a given Circular linked list */
void printList(struct Node *head)
{
struct Node *temp = head;
if(head != NULL)
{
printf("\n");
do {
printf("%d ", temp->data);
temp = temp->next;
} while(temp != head);
}
}
/* Driver program to test above functions */
int main()
{
int list_size, i;
/* Initialize lists as empty */
struct Node *head = NULL;
struct Node *head1 = NULL;
struct Node *head2 = NULL;
/* Created linked list will be 12->56->2->11 */
push(&head, 12);
push(&head, 56);
push(&head, 2);
push(&head, 11);
printf("Original Circular Linked List");
printList(head);
/* Split the list */
splitList(head, &head1, &head2);
printf("\nFirst Circular Linked List");
printList(head1);
printf("\nSecond Circular Linked List");
printList(head2);
getchar();
return 0;
}
Java
// Java program to delete a node from doubly linked list
class LinkedList {
static Node head, head1, head2;
static class Node {
int data;
Node next, prev;
Node(int d) {
data = d;
next = prev = null;
}
}
/* Function to split a list (starting with head) into two lists.
head1_ref and head2_ref are references to head nodes of
the two resultant linked lists */
void splitList() {
Node slow_ptr = head;
Node fast_ptr = head;
if (head == null) {
return;
}
/* If there are odd nodes in the circular list then
fast_ptr->next becomes head and for even nodes
fast_ptr->next->next becomes head */
while (fast_ptr.next != head
&& fast_ptr.next.next != head) {
fast_ptr = fast_ptr.next.next;
slow_ptr = slow_ptr.next;
}
/* If there are even elements in list then move fast_ptr */
if (fast_ptr.next.next == head) {
fast_ptr = fast_ptr.next;
}
/* Set the head pointer of first half */
head1 = head;
/* Set the head pointer of second half */
if (head.next != head) {
head2 = slow_ptr.next;
}
/* Make second half circular */
fast_ptr.next = slow_ptr.next;
/* Make first half circular */
slow_ptr.next = head;
}
/* Function to print nodes in a given singly linked list */
void printList(Node node) {
Node temp = node;
if (node != null) {
do {
System.out.print(temp.data + " ");
temp = temp.next;
} while (temp != node);
}
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
//Created linked list will be 12->56->2->11
list.head = new Node(12);
list.head.next = new Node(56);
list.head.next.next = new Node(2);
list.head.next.next.next = new Node(11);
list.head.next.next.next.next = list.head;
System.out.println("Original Circular Linked list ");
list.printList(head);
// Split the list
list.splitList();
System.out.println("");
System.out.println("First Circular List ");
list.printList(head1);
System.out.println("");
System.out.println("Second Circular List ");
list.printList(head2);
}
}
// This code has been contributed by Mayank Jaiswal
Python
# Python program to split circular linked list into two halves
# A node structure
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.next = None
# Class to create a new Circular Linked list
class CircularLinkedList:
# Constructor to create a empty circular linked list
def __init__(self):
self.head = None
# Function to insert a node at the beginning of a
# circular linked list
def push(self, data):
ptr1 = Node(data)
temp = self.head
ptr1.next = self.head
# If linked list is not None then set the next of
# last node
if self.head is not None:
while(temp.next != self.head):
temp = temp.next
temp.next = ptr1
else:
ptr1.next = ptr1 # For the first node
self.head = ptr1
# Function to print nodes in a given circular linked list
def printList(self):
temp = self.head
if self.head is not None:
while(True):
print "%d" %(temp.data),
temp = temp.next
if (temp == self.head):
break
# Function to split a list (starting with head) into
# two lists. head1 and head2 are the head nodes of the
# two resultant linked lists
def splitList(self, head1, head2):
slow_ptr = self.head
fast_ptr = self.head
if self.head is None:
return
# If htere are odd nodes in the circular list then
# fast_ptr->next becomes head and for even nodes
# fast_ptr->next->next becomes head
while(fast_ptr.next != self.head and
fast_ptr.next.next != self.head ):
fast_ptr = fast_ptr.next.next
slow_ptr = slow_ptr.next
# If there are even elements in list then
# move fast_ptr
if fast_ptr.next.next == self.head:
fast_ptr = fast_ptr.next
# Set the head pointer of first half
head1.head = self.head
# Set the head pointer of second half
if self.head.next != self.head:
head2.head = slow_ptr.next
# Make second half circular
fast_ptr.next = slow_ptr.next
# Make first half circular
slow_ptr.next = self.head
# Driver program to test above functions
# Initialize lists as empty
head = CircularLinkedList()
head1 = CircularLinkedList()
head2 = CircularLinkedList()
head.push(12)
head.push(56)
head.push(2)
head.push(11)
print "Original Circular Linked List"
head.printList()
# Split the list
head.splitList(head1 , head2)
print "\nFirst Circular Linked List"
head1.printList()
print "\nSecond Circular Linked List"
head2.printList()
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)
C#
// C# program to delete a node
// from doubly linked list
using System;
class GFG
{
public Node head, head1, head2;
public class Node
{
public int data;
public Node next, prev;
public Node(int d)
{
data = d;
next = prev = null;
}
}
/* Function to split a list (starting with head)
into two lists. head1_ref and head2_ref are
references to head nodes of the two
resultant linked lists */
void splitList()
{
Node slow_ptr = head;
Node fast_ptr = head;
if (head == null)
{
return;
}
/* If there are odd nodes in the
circular list then fast_ptr->next
becomes head and for even nodes
fast_ptr->next->next becomes head */
while (fast_ptr.next != head &&
fast_ptr.next.next != head)
{
fast_ptr = fast_ptr.next.next;
slow_ptr = slow_ptr.next;
}
/* If there are even elements in list
then move fast_ptr */
if (fast_ptr.next.next == head)
{
fast_ptr = fast_ptr.next;
}
/* Set the head pointer of first half */
head1 = head;
/* Set the head pointer of second half */
if (head.next != head)
{
head2 = slow_ptr.next;
}
/* Make second half circular */
fast_ptr.next = slow_ptr.next;
/* Make first half circular */
slow_ptr.next = head;
}
/* Function to print nodes
in a given singly linked list */
void printList(Node node)
{
Node temp = node;
if (node != null)
{
do
{
Console.Write(temp.data + " ");
temp = temp.next;
} while (temp != node);
}
}
public static void Main(String[] args)
{
GFG list = new GFG();
// Created linked list will be 12->56->2->11
list.head = new Node(12);
list.head.next = new Node(56);
list.head.next.next = new Node(2);
list.head.next.next.next = new Node(11);
list.head.next.next.next.next = list.head;
Console.WriteLine("Original Circular Linked list ");
list.printList(list.head);
// Split the list
list.splitList();
Console.WriteLine("");
Console.WriteLine("First Circular List ");
list.printList(list.head1);
Console.WriteLine("");
Console.WriteLine("Second Circular List ");
list.printList(list.head2);
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
Original Circular Linked List
11 2 56 12
First Circular Linked List
11 2
Second Circular Linked List
56 12
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。