用于将元素的所有出现移动到以链表结尾的Java程序
给定一个链表和其中的一个键,任务是将所有出现的给定键移动到链表的末尾,保持所有其他元素的顺序相同。
例子:
Input : 1 -> 2 -> 2 -> 4 -> 3
key = 2
Output : 1 -> 4 -> 3 -> 2 -> 2
Input : 6 -> 6 -> 7 -> 6 -> 3 -> 10
key = 6
Output : 7 -> 3 -> 10 -> 6 -> 6 -> 6
一个简单的解决方案是在链表中逐一查找给定键的所有出现。对于每个找到的事件,将其插入到末尾。我们这样做直到给定键的所有出现都移到最后。
时间复杂度: O(n 2 )
有效的解决方案1:是保留两个指针:
pCrawl => 一个一个遍历整个列表的指针。
pKey => 如果找到键,则指向该键的出现。其他与 pCrawl 相同。
我们从链表的头部开始上述两个指针。只有当pKey不指向某个键时,我们才移动pKey 。我们总是移动pCrawl 。所以,当pCrawl和pKey不相同时,我们肯定已经找到了一个位于pCrawl之前的 key,所以我们在pCrawl和pKey之间交换,并将pKey移动到下一个位置。循环不变量是,在交换数据之后,从pKey到pCrawl的所有元素都是键。
下面是这种方法的实现。
Java
// Java program to move all occurrences of a
// given key to end.
class GFG {
// A Linked list Node
static class Node {
int data;
Node next;
}
// A utility function to create a new node.
static Node newNode(int x)
{
Node temp = new Node();
temp.data = x;
temp.next = null;
return temp;
}
// Utility function to print the elements
// in Linked list
static void printList(Node head)
{
Node temp = head;
while (temp != null) {
System.out.printf("%d ", temp.data);
temp = temp.next;
}
System.out.printf("
");
}
// Moves all occurrences of given key to
// end of linked list.
static void moveToEnd(Node head, int key)
{
// Keeps track of locations where key
// is present.
Node pKey = head;
// Traverse list
Node pCrawl = head;
while (pCrawl != null) {
// If current pointer is not same as pointer
// to a key location, then we must have found
// a key in linked list. We swap data of pCrawl
// and pKey and move pKey to next position.
if (pCrawl != pKey && pCrawl.data != key) {
pKey.data = pCrawl.data;
pCrawl.data = key;
pKey = pKey.next;
}
// Find next position where key is present
if (pKey.data != key)
pKey = pKey.next;
// Moving to next Node
pCrawl = pCrawl.next;
}
}
// Driver code
public static void main(String args[])
{
Node head = newNode(10);
head.next = newNode(20);
head.next.next = newNode(10);
head.next.next.next = newNode(30);
head.next.next.next.next = newNode(40);
head.next.next.next.next.next = newNode(10);
head.next.next.next.next.next.next = newNode(60);
System.out.printf("Before moveToEnd(), the Linked list is
");
printList(head);
int key = 10;
moveToEnd(head, key);
System.out.printf("
After moveToEnd(), the Linked list is
");
printList(head);
}
}
// This code is contributed by Arnab Kundu
Java
// Java code to remove key element to end of linked list
import java.util.*;
// Node class
class Node {
int data;
Node next;
public Node(int data)
{
this.data = data;
this.next = null;
}
}
class gfg {
static Node root;
// Function to remove key to end
public static Node keyToEnd(Node head, int key)
{
// Node to keep pointing to tail
Node tail = head;
if (head == null) {
return null;
}
while (tail.next != null) {
tail = tail.next;
}
// Node to point to last of linked list
Node last = tail;
Node current = head;
Node prev = null;
// Node prev2 to point to previous when head.data!=key
Node prev2 = null;
// loop to perform operations to remove key to end
while (current != tail) {
if (current.data == key && prev2 == null) {
prev = current;
current = current.next;
head = current;
last.next = prev;
last = last.next;
last.next = null;
prev = null;
}
else {
if (current.data == key && prev2 != null) {
prev = current;
current = current.next;
prev2.next = current;
last.next = prev;
last = last.next;
last.next = null;
}
else if (current != tail) {
prev2 = current;
current = current.next;
}
}
}
return head;
}
// Function to display linked list
public static void display(Node root)
{
while (root != null) {
System.out.print(root.data + " ");
root = root.next;
}
}
// Driver Code
public static void main(String args[])
{
root = new Node(5);
root.next = new Node(2);
root.next.next = new Node(2);
root.next.next.next = new Node(7);
root.next.next.next.next = new Node(2);
root.next.next.next.next.next = new Node(2);
root.next.next.next.next.next.next = new Node(2);
int key = 2;
System.out.println("Linked List before operations :");
display(root);
System.out.println("
Linked List after operations :");
root = keyToEnd(root, key);
display(root);
}
}
输出:
Before moveToEnd(), the Linked list is
10 20 10 30 40 10 60
After moveToEnd(), the Linked list is
20 30 40 60 10 10 10
时间复杂度: O(n) 只需要遍历一次列表。
高效解决方案 2:
1. 遍历链表,在尾部取一个指针。
2. 现在,检查密钥和节点->数据。如果它们相等,则将节点移动到 last-next,否则继续前进。
Java
// Java code to remove key element to end of linked list
import java.util.*;
// Node class
class Node {
int data;
Node next;
public Node(int data)
{
this.data = data;
this.next = null;
}
}
class gfg {
static Node root;
// Function to remove key to end
public static Node keyToEnd(Node head, int key)
{
// Node to keep pointing to tail
Node tail = head;
if (head == null) {
return null;
}
while (tail.next != null) {
tail = tail.next;
}
// Node to point to last of linked list
Node last = tail;
Node current = head;
Node prev = null;
// Node prev2 to point to previous when head.data!=key
Node prev2 = null;
// loop to perform operations to remove key to end
while (current != tail) {
if (current.data == key && prev2 == null) {
prev = current;
current = current.next;
head = current;
last.next = prev;
last = last.next;
last.next = null;
prev = null;
}
else {
if (current.data == key && prev2 != null) {
prev = current;
current = current.next;
prev2.next = current;
last.next = prev;
last = last.next;
last.next = null;
}
else if (current != tail) {
prev2 = current;
current = current.next;
}
}
}
return head;
}
// Function to display linked list
public static void display(Node root)
{
while (root != null) {
System.out.print(root.data + " ");
root = root.next;
}
}
// Driver Code
public static void main(String args[])
{
root = new Node(5);
root.next = new Node(2);
root.next.next = new Node(2);
root.next.next.next = new Node(7);
root.next.next.next.next = new Node(2);
root.next.next.next.next.next = new Node(2);
root.next.next.next.next.next.next = new Node(2);
int key = 2;
System.out.println("Linked List before operations :");
display(root);
System.out.println("
Linked List after operations :");
root = keyToEnd(root, key);
display(root);
}
}
输出:
Linked List before operations :
5 2 2 7 2 2 2
Linked List after operations :
5 7 2 2 2 2 2
感谢Ravinder Kumar提出这种方法。
高效的解决方案3:是维护一个单独的键列表。我们将此键列表初始化为空。我们遍历给定的列表。对于找到的每个键,我们将其从原始列表中删除并将其插入到单独的键列表中。我们最终将键列表链接到剩余给定列表的末尾。该解决方案的时间复杂度也是 O(n),而且它也只需要遍历一次列表。
有关详细信息,请参阅有关将所有出现的元素移动到链接列表中的完整文章!