📌  相关文章
📜  用于将元素的所有出现移动到以链表结尾的Java程序

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

用于将元素的所有出现移动到以链表结尾的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 。所以,当pCrawlpKey不相同时,我们肯定已经找到了一个位于pCrawl之前的 key,所以我们在pCrawlpKey之间交换,并将pKey移动到下一个位置。循环不变量是,在交换数据之后,从pKeypCrawl的所有元素都是键。

下面是这种方法的实现。

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),而且它也只需要遍历一次列表。

有关详细信息,请参阅有关将所有出现的元素移动到链接列表中的完整文章!