📌  相关文章
📜  用于交换链表中的节点而不交换数据的Java程序

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

用于交换链表中的节点而不交换数据的Java程序

给定一个链表和其中的两个键,交换两个给定键的节点。节点应该通过改变链接来交换。当数据包含许多字段时,在许多情况下交换节点的数据可能会很昂贵。

可以假设链表中的所有键都是不同的。

例子:

Input : 10->15->12->13->20->14,  x = 12, y = 20
Output: 10->15->20->13->12->14

Input : 10->15->12->13->20->14,  x = 10, y = 20
Output: 20->15->12->13->10->14

Input : 10->15->12->13->20->14,  x = 12, y = 13
Output: 10->15->13->12->20->14

这可能看起来是一个简单的问题,但却是一个有趣的问题,因为它需要处理以下情况。

  1. x 和 y 可能相邻也可能不相邻。
  2. x 或 y 都可以是头节点。
  3. x 或 y 可能是最后一个节点。
  4. x 和/或 y 可能不存在于链表中。

如何编写一个干净的工作代码来处理上述所有可能性。

这个想法是首先在给定的链表中搜索 x 和 y。如果其中任何一个都不存在,则返回。在搜索 x 和 y 时,跟踪当前和以前的指针。首先更改前一个指针的下一个,然后更改当前指针的下一个。

下面是上述方法的实现。

Java
// Java program to swap two given nodes
// of a linked list
class Node
{
    int data;
    Node next;
    Node(int d)
    {
        data = d;
        next = null;
    }
}
 
class LinkedList
{
    // head of list
    Node head;
 
    /* Function to swap Nodes x and y in
       linked list by changing links */
    public void swapNodes(int x, int y)
    {
        // Nothing to do if x and y
        // are same
        if (x == y)
            return;
 
        // Search for x (keep track of
        // prevX and CurrX)
        Node prevX = null, currX = head;
        while (currX != null &&
               currX.data != x)
        {
            prevX = currX;
            currX = currX.next;
        }
 
        // Search for y (keep track of
        // prevY and currY)
        Node prevY = null, currY = head;
        while (currY != null &&
               currY.data != y)
        {
            prevY = currY;
            currY = currY.next;
        }
 
        // If either x or y is not present,
        // nothing to do
        if (currX == null || currY == null)
            return;
 
        // If x is not head of linked list
        if (prevX != null)
            prevX.next = currY;
        else // make y the new head
            head = currY;
 
        // If y is not head of linked list
        if (prevY != null)
            prevY.next = currX;
        else // make x the new head
            head = currX;
 
        // Swap next pointers
        Node temp = currX.next;
        currX.next = currY.next;
        currY.next = temp;
    }
 
    // Function to add Node at
    // beginning of list.
    public void push(int new_data)
    {
        // 1. alloc the Node and put the data
        Node new_Node = new Node(new_data);
 
        // 2. Make next of new Node as head
        new_Node.next = head;
 
        // 3. Move the head to point to new Node
        head = new_Node;
    }
 
    /* This function prints contents of
       linked list starting from the given Node */
    public void printList()
    {
        Node tNode = head;
        while (tNode != null)
        {
            System.out.print(tNode.data + " ");
            tNode = tNode.next;
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
        LinkedList llist = new LinkedList();
 
        /* The constructed linked list is:
           1->2->3->4->5->6->7 */
        llist.push(7);
        llist.push(6);
        llist.push(5);
        llist.push(4);
        llist.push(3);
        llist.push(2);
        llist.push(1);
 
        System.out.print(
               "Linked list before calling swapNodes() ");
        llist.printList();
        llist.swapNodes(4, 3);
        System.out.print(
               "Linked list after calling swapNodes() ");
        llist.printList();
    }
}
// This code is contributed by Rajat Mishra


Java
// Java program to swap two given nodes
// of a linked list
public class Solution
{
    // Represent a node of the
    // singly linked list
    class Node
    {
        int data;
        Node next;
 
        public Node(int data)
        {
            this.data = data;
            this.next = null;
        }
    }
 
    // Represent the head and tail
    // of the singly linked list
    public Node head = null;
    public Node tail = null;
 
    // addNode() will add a new node
    // to the list
    public void addNode(int data)
    {
        // Create a new node
        Node newNode = new Node(data);
 
        // Checks if the list is empty
        if (head == null)
        {
            // If list is empty, both head and
            // tail will point to new node
            head = newNode;
            tail = newNode;
        }
        else
        {
            // newNode will be added after tail
            // such that tail's next will point
            // to newNode
            tail.next = newNode;
            // newNode will become new tail of
            // the list
            tail = newNode;
        }
    }
 
    // swap() will swap the given two nodes
    public void swap(int n1, int n2)
    {
        Node prevNode1 = null, prevNode2 = null,
             node1 = head, node2 = head;
 
        // Checks if list is empty
        if (head == null)
        {
            return;
        }
 
        // If n1 and n2 are equal, then
        // list will remain the same
        if (n1 == n2)
            return;
 
        // Search for node1
        while (node1 != null &&
               node1.data != n1)
        {
            prevNode1 = node1;
            node1 = node1.next;
        }
 
        // Search for node2
        while (node2 != null &&
               node2.data != n2)
        {
            prevNode2 = node2;
            node2 = node2.next;
        }
 
        if (node1 != null &&
            node2 != null)
        {
            // If previous node to node1 is not
            // null then, it will point to node2
            if (prevNode1 != null)
                prevNode1.next = node2;
            else
                head = node2;
 
            // If previous node to node2 is not
            // null then, it will point to node1
            if (prevNode2 != null)
                prevNode2.next = node1;
            else
                head = node1;
 
            // Swaps the next nodes of node1
            // and node2
            Node temp = node1.next;
            node1.next = node2.next;
            node2.next = temp;
        }
        else
        {
            System.out.println("Swapping is not possible");
        }
    }
 
    // display() will display all the
    // nodes present in the list
    public void display()
    {
        // Node current will point to head
        Node current = head;
 
        if (head == null)
        {
            System.out.println("List is empty");
            return;
        }
        while (current != null)
        {
            // Prints each node by incrementing
            // pointer
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
 
    public static void main(String[] args)
    {
        Solution sList = new Solution();
 
        // Add nodes to the list
        sList.addNode(1);
        sList.addNode(2);
        sList.addNode(3);
        sList.addNode(4);
        sList.addNode(5);
        sList.addNode(6);
        sList.addNode(7);
 
        System.out.println("Original list: ");
        sList.display();
 
        // Swaps the node 2 with node 5
        sList.swap(6, 1);
 
        System.out.println(
               "List after swapping nodes: ");
        sList.display();
    }
}


输出:

Linked list before calling swapNodes() 1 2 3 4 5 6 7 
Linked list after calling swapNodes() 1 2 4 3 5 6 7 

时间复杂度: O(n)

辅助空间: O(1)

优化:上面的代码可以优化为在单次遍历中搜索 x 和 y。两个循环用于保持程序简单。

更简单的方法:

Java

// Java program to swap two given nodes
// of a linked list
public class Solution
{
    // Represent a node of the
    // singly linked list
    class Node
    {
        int data;
        Node next;
 
        public Node(int data)
        {
            this.data = data;
            this.next = null;
        }
    }
 
    // Represent the head and tail
    // of the singly linked list
    public Node head = null;
    public Node tail = null;
 
    // addNode() will add a new node
    // to the list
    public void addNode(int data)
    {
        // Create a new node
        Node newNode = new Node(data);
 
        // Checks if the list is empty
        if (head == null)
        {
            // If list is empty, both head and
            // tail will point to new node
            head = newNode;
            tail = newNode;
        }
        else
        {
            // newNode will be added after tail
            // such that tail's next will point
            // to newNode
            tail.next = newNode;
            // newNode will become new tail of
            // the list
            tail = newNode;
        }
    }
 
    // swap() will swap the given two nodes
    public void swap(int n1, int n2)
    {
        Node prevNode1 = null, prevNode2 = null,
             node1 = head, node2 = head;
 
        // Checks if list is empty
        if (head == null)
        {
            return;
        }
 
        // If n1 and n2 are equal, then
        // list will remain the same
        if (n1 == n2)
            return;
 
        // Search for node1
        while (node1 != null &&
               node1.data != n1)
        {
            prevNode1 = node1;
            node1 = node1.next;
        }
 
        // Search for node2
        while (node2 != null &&
               node2.data != n2)
        {
            prevNode2 = node2;
            node2 = node2.next;
        }
 
        if (node1 != null &&
            node2 != null)
        {
            // If previous node to node1 is not
            // null then, it will point to node2
            if (prevNode1 != null)
                prevNode1.next = node2;
            else
                head = node2;
 
            // If previous node to node2 is not
            // null then, it will point to node1
            if (prevNode2 != null)
                prevNode2.next = node1;
            else
                head = node1;
 
            // Swaps the next nodes of node1
            // and node2
            Node temp = node1.next;
            node1.next = node2.next;
            node2.next = temp;
        }
        else
        {
            System.out.println("Swapping is not possible");
        }
    }
 
    // display() will display all the
    // nodes present in the list
    public void display()
    {
        // Node current will point to head
        Node current = head;
 
        if (head == null)
        {
            System.out.println("List is empty");
            return;
        }
        while (current != null)
        {
            // Prints each node by incrementing
            // pointer
            System.out.print(current.data + " ");
            current = current.next;
        }
        System.out.println();
    }
 
    public static void main(String[] args)
    {
        Solution sList = new Solution();
 
        // Add nodes to the list
        sList.addNode(1);
        sList.addNode(2);
        sList.addNode(3);
        sList.addNode(4);
        sList.addNode(5);
        sList.addNode(6);
        sList.addNode(7);
 
        System.out.println("Original list: ");
        sList.display();
 
        // Swaps the node 2 with node 5
        sList.swap(6, 1);
 
        System.out.println(
               "List after swapping nodes: ");
        sList.display();
    }
}

输出:

Linked list before calling swapNodes() 1 2 3 4 5 6 7 
Linked list after calling swapNodes() 6 2 3 4 5 1 7 

时间复杂度: O(n)

辅助空间: O(1)

请参考完整的文章在链表中交换节点而不交换数据以获取更多详细信息!