在不修改数据的情况下对给定的二进制双向链表进行排序
给定包含0和1的双向链表的头和尾,任务是在不修改数据的情况下对双向链表进行排序。
例子:
Input: head = 1->1->0->0->1->0->1->1->0->0->NULL
Output: 0->0->0->0->0->1->1->1->1->1->NULL
Input: head = 1->0->NULL
Output: 0->1->NULL
方法:解决这个问题的想法是使用两个指针算法,如下所述:
- Create two pointers – head and tail such that head points at first element and tail points at last element
- Keep checking the element at the pointers for 1 at head and 0 at tail,
- Swap the elements whenever 1, 0 combination is found.
请按照以下步骤解决问题:
- 初始化第一个指针 = 头,最后一个指针 = 尾
- 虽然first != last和first -> prev != last
- 检查,如果first->data == 0
- 更新,第一个 = 第一个-> 下一个
- 如果,最后->数据 == 1
- 更新,最后 = 最后->上一个
- 如果,first->data == 1 和 last->data == 0
- 然后,交换第一个和最后一个节点
- 再次交换第一个和最后一个指针
- 首先向右移动,最后向左移动1
下面是上述方法的实现:
C++
// C++ program for the above approach:
#include
using namespace std;
// Link list Node Class
class Node {
public:
int data;
Node* prev;
Node* next;
// Constructor function
Node(int data)
{
this->data = data;
this->prev = NULL;
this->next = NULL;
}
};
// Function to print linked list
void print(Node* head)
{
Node* temp = head;
// Iterate until node is NOT NULL
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
// Function to push a node in
// Doubly linked- list
void push(Node*& head, Node*& tail, int item)
{
// If list is empty
if (tail == NULL) {
Node* temp = new Node(item);
tail = temp;
head = temp;
}
// List is not empty
else {
Node* temp = new Node(item);
tail->next = temp;
temp->prev = tail;
tail = temp;
}
}
// Function to swap the list
// Consisting of 0s and 1s
void swap(Node*& Node1, Node*& Node2)
{
Node* temp;
temp = Node1->next;
Node1->next = Node2->next;
Node2->next = temp;
if (Node1->next != NULL)
Node1->next->prev = Node1;
if (Node2->next != NULL)
Node2->next->prev = Node2;
temp = Node1->prev;
Node1->prev = Node2->prev;
Node2->prev = temp;
if (Node1->prev != NULL)
Node1->prev->next = Node1;
if (Node2->prev != NULL)
Node2->prev->next = Node2;
}
// Function to sort the list
// Consisting of 0s and 1s
void sort(Node*& head, Node*& tail)
{
// Base Case
if (head == tail || head == NULL)
return;
// Initialize the pointers
Node* first = head;
Node* last = tail;
while ((first != last)
&& (first->prev != last)) {
// If first->data is 0 then move
// First towards right by 1
if (first->data == 0)
first = first->next;
// If last->data is 1 then move
// Last towards left by 1
if (last->data == 1)
last = last->prev;
// If first->data is 1 and last->data is 0
// then swap first and last node
if (first->data == 1 && last->data == 0
&& first->prev != last) {
// Swapping the node
swap(first, last);
// if head = 1
if (head == first)
head = last;
// if tail == 0
if (tail == last)
tail = first;
// Swapping the pointer and
// moved to next iteration
Node* Temp = first;
first = last->next;
last = Temp->prev;
}
}
}
// Driver Code
int main()
{
Node* head = NULL;
Node* tail = NULL;
push(head, tail, 1);
push(head, tail, 1);
push(head, tail, 0);
push(head, tail, 0);
push(head, tail, 1);
push(head, tail, 0);
push(head, tail, 1);
push(head, tail, 1);
push(head, tail, 0);
push(head, tail, 0);
sort(head, tail);
print(head);
return 0;
}
Java
// Java program for the above approach:
import java.util.*;
class GFG{
static Node head;
static Node tail;
// Link list Node Class
static class Node {
int data;
Node prev;
Node next;
// Constructor function
Node(int data)
{
this.data = data;
this.prev = null;
this.next = null;
}
};
// Function to print linked list
static void print(Node head)
{
Node temp = head;
// Iterate until node is NOT null
while (temp != null) {
System.out.print(temp.data+ " ");
temp = temp.next;
}
System.out.println();
}
// Function to push a node in
// Doubly linked- list
static void push(int item)
{
// If list is empty
if (tail == null) {
Node temp = new Node(item);
tail = temp;
head = temp;
}
// List is not empty
else {
Node temp = new Node(item);
tail.next = temp;
temp.prev = tail;
tail = temp;
}
}
// Function to swap the list
// Consisting of 0s and 1s
static void swap(Node Node1, Node Node2)
{
Node temp;
temp = Node1.next;
Node1.next = Node2.next;
Node2.next = temp;
if (Node1.next != null)
Node1.next.prev = Node1;
if (Node2.next != null)
Node2.next.prev = Node2;
temp = Node1.prev;
Node1.prev = Node2.prev;
Node2.prev = temp;
if (Node1.prev != null)
Node1.prev.next = Node1;
if (Node2.prev != null)
Node2.prev.next = Node2;
}
// Function to sort the list
// Consisting of 0s and 1s
static void sort()
{
// Base Case
if (head == tail || head == null)
return;
// Initialize the pointers
Node first = head;
Node last = tail;
while ((first != last)
&& (first.prev != last)) {
// If first.data is 0 then move
// First towards right by 1
if (first.data == 0)
first = first.next;
// If last.data is 1 then move
// Last towards left by 1
if (last.data == 1)
last = last.prev;
// If first.data is 1 and last.data is 0
// then swap first and last node
if (first.data == 1 && last.data == 0
&& first.prev != last) {
// Swapping the node
swap(first, last);
// if head = 1
if (head == first)
head = last;
// if tail == 0
if (tail == last)
tail = first;
// Swapping the pointer and
// moved to next iteration
Node Temp = first;
first = last.next;
last = Temp.prev;
}
}
}
// Driver Code
public static void main(String[] args)
{
push(1);
push(1);
push(0);
push(0);
push(1);
push(0);
push(1);
push(1);
push(0);
push(0);
sort();
print(head);
}
}
// This code is contributed by 29AjayKumar
C#
// C# program for the above approach:
using System;
using System.Collections.Generic;
public class GFG{
static Node head;
static Node tail;
// Link list Node Class
public class Node {
public int data;
public Node prev;
public Node next;
// Constructor function
public Node(int data)
{
this.data = data;
this.prev = null;
this.next = null;
}
};
// Function to print linked list
static void print(Node head)
{
Node temp = head;
// Iterate until node is NOT null
while (temp != null) {
Console.Write(temp.data+ " ");
temp = temp.next;
}
Console.WriteLine();
}
// Function to push a node in
// Doubly linked- list
static void push(int item)
{
// If list is empty
if (tail == null) {
Node temp = new Node(item);
tail = temp;
head = temp;
}
// List is not empty
else {
Node temp = new Node(item);
tail.next = temp;
temp.prev = tail;
tail = temp;
}
}
// Function to swap the list
// Consisting of 0s and 1s
static void swap(Node Node1, Node Node2)
{
Node temp;
temp = Node1.next;
Node1.next = Node2.next;
Node2.next = temp;
if (Node1.next != null)
Node1.next.prev = Node1;
if (Node2.next != null)
Node2.next.prev = Node2;
temp = Node1.prev;
Node1.prev = Node2.prev;
Node2.prev = temp;
if (Node1.prev != null)
Node1.prev.next = Node1;
if (Node2.prev != null)
Node2.prev.next = Node2;
}
// Function to sort the list
// Consisting of 0s and 1s
static void sort()
{
// Base Case
if (head == tail || head == null)
return;
// Initialize the pointers
Node first = head;
Node last = tail;
while ((first != last)
&& (first.prev != last)) {
// If first.data is 0 then move
// First towards right by 1
if (first.data == 0)
first = first.next;
// If last.data is 1 then move
// Last towards left by 1
if (last.data == 1)
last = last.prev;
// If first.data is 1 and last.data is 0
// then swap first and last node
if (first.data == 1 && last.data == 0
&& first.prev != last) {
// Swapping the node
swap(first, last);
// if head = 1
if (head == first)
head = last;
// if tail == 0
if (tail == last)
tail = first;
// Swapping the pointer and
// moved to next iteration
Node Temp = first;
first = last.next;
last = Temp.prev;
}
}
}
// Driver Code
public static void Main(String[] args)
{
push(1);
push(1);
push(0);
push(0);
push(1);
push(0);
push(1);
push(1);
push(0);
push(0);
sort();
print(head);
}
}
// This code is contributed by shikhasingrajput
输出
0 0 0 0 0 1 1 1 1 1
时间复杂度:O(N)
辅助空间:O(1)