📌  相关文章
📜  在双向链表中从头开始与第 K 个节点交换第 K 个节点

📅  最后修改于: 2021-09-07 02:03:45             🧑  作者: Mango

先决条件:双向链表
给定一个双向链表,任务是将开头的K节点与结尾的K节点交换。
注意:请注意这里交换的是节点而不是节点中的数据。
例子:

做法:思路是从头开始遍历到第K元素,从结尾开始遍历到K节点,改变前后指针。设K1是从头开始的第K节点,而K2是从结束开始的K节点。然后:

  • K2的前一个节点必须更改为K1的前一个节点。
  • K2的下一个节点必须更改为K1的下一个节点。
  • K1的前一个节点必须更改为K2的前一个节点。
  • K1的下一个节点必须更改为K2的下一个节点。

下面是上述方法的实现:

Java
// Java implementation of the approach
 
public class GFG {
 
    // Doubly Linked List implementation
    private class Node {
        private int data;
        private Node next;
        private Node previous;
 
        public Node(int data, Node next,
                    Node previous)
        {
            this.data = data;
            this.next = next;
            this.previous = previous;
        }
 
        public int getData()
        {
            return data;
        }
 
        public void setData(int data)
        {
            this.data = data;
        }
 
        public Node getNext()
        {
            return next;
        }
 
        public void setNext(Node next)
        {
            this.next = next;
        }
 
        public Node getPrevious()
        {
            return previous;
        }
 
        public void setPrevious(Node previous)
        {
            this.previous = previous;
        }
    }
 
    private Node head;
    private Node tail;
 
    public GFG()
    {
        this.head = null;
        this.tail = null;
    }
 
    public Node getHead()
    {
        return head;
    }
 
    public void setHead(Node head)
    {
        this.head = head;
    }
 
    public Node getTail()
    {
        return tail;
    }
 
    public void setTail(Node tail)
    {
        this.tail = tail;
    }
 
    // Function to replace Kth node from
    // beginning with Kth node from end
    public void swapNode(Node headReference,
                         Node tailReference, int k)
    {
 
        // If K is 1, then the first node
        // has to be swapped with the
        // last node in the doubly linked list
        if (k == 1) {
            swapFirstAndLast(headReference,
                             tailReference);
            return;
        }
 
        // If k is N, then the last node
        // has to be swapped with the
        // first node in the doubly linked list
        int nodeCount = getCount(headReference);
        if (k == nodeCount) {
            swapFirstAndLast(headReference,
                             tailReference);
            return;
        }
 
        // If the Kth node from
        // the beginning and Kth node
        // from the ending are same
        if (2 * k - 1 == nodeCount) {
            return;
        }
 
        // fNode represents Kth node
        // from the beginning
        Node fNode = headReference;
        for (int i = 1; i < k; i++) {
            fNode = fNode.getNext();
        }
        Node fNodePrevious = fNode.getPrevious();
        Node fNodeNext = fNode.getNext();
 
        // sNode represents Kth node
        // from the ending
        Node sNode = tailReference;
        for (int i = 1; i < k; i++) {
            sNode = sNode.getPrevious();
        }
 
        Node sNodePrevious = sNode.getPrevious();
        Node sNodeNext = sNode.getNext();
 
        // Checking if any of the pointers is null
        // and interchanging the pointers
        if (fNodePrevious != null && sNode != null) {
 
            fNodePrevious.setNext(sNode);
            sNode.setPrevious(fNodePrevious);
            sNode.setNext(fNodeNext);
            fNodeNext.setPrevious(sNode);
        }
        if (sNodePrevious != null && sNodeNext != null) {
 
            sNodeNext.setPrevious(fNode);
            fNode.setNext(sNodeNext);
            sNodePrevious.setNext(fNode);
            fNode.setPrevious(sNodePrevious);
        }
    }
 
    // Function to swap the first and
    // last node in the doubly linked list
    private void swapFirstAndLast(
        Node headReference,
        Node tailReference)
    {
        Node headRef = headReference;
        Node tailRef = tailReference;
 
        headReference
            = headReference.getNext();
        tailReference
            = tailReference.getPrevious();
 
        tailReference.setNext(headRef);
        headRef.setPrevious(tailReference);
        headRef.setNext(null);
        this.setTail(tailReference.getNext());
 
        headReference.setPrevious(tailRef);
        tailRef.setNext(headReference);
        tailRef.setPrevious(null);
        this.setHead(headReference
                         .getPrevious());
    }
 
    // Function to return the number of nodes
    // in the linked list
    private int getCount(Node headReference)
    {
        int nodeCount = 0;
        while (headReference != null) {
            nodeCount++;
            headReference = headReference
                                .getNext();
        }
        return nodeCount;
    }
 
    // Function to print the Linked List
    public void printList(Node headReference)
    {
        if (headReference == null) {
            System.out.println(
                "Doubly linked list is empty");
            return;
        }
        else {
            while (headReference != null) {
                System.out.print(
                    headReference.getData()
                    + " ");
                headReference
                    = headReference.getNext();
            }
        }
    }
 
    // Function to insert a node at
    // the end of the doubly linked list
    public void push(int data)
    {
        Node newNode
            = new Node(data, null, null);
 
        if (head == null) {
            head = tail = newNode;
        }
        else {
            tail.setNext(newNode);
            newNode.setPrevious(tail);
            tail = newNode;
        }
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // Creating an object for the class
        GFG list = new GFG();
 
        // Adding data to the linked list
        list.push(1);
        list.push(2);
        list.push(3);
        list.push(4);
        list.push(5);
 
        // Calling the function
        int K = 2;
        list.swapNode(list.getHead(),
                      list.getTail(), K);
        list.printList(list.getHead());
    }
}


C#
// C# implementation of the approach
using System;
public class GFG {
  
    // Doubly Linked List implementation
    private class Node {
        private int data;
        private Node next;
        private Node previous;
  
        public Node(int data, Node next,
                    Node previous)
        {
            this.data = data;
            this.next = next;
            this.previous = previous;
        }
  
        public int getData()
        {
            return data;
        }
  
        public void setData(int data)
        {
            this.data = data;
        }
  
        public Node getNext()
        {
            return next;
        }
  
        public void setNext(Node next)
        {
            this.next = next;
        }
  
        public Node getPrevious()
        {
            return previous;
        }
  
        public void setPrevious(Node previous)
        {
            this.previous = previous;
        }
    }
  
    private Node head;
    private Node tail;
  
    public GFG()
    {
        this.head = null;
        this.tail = null;
    }
  
    Node getHead()
    {
        return head;
    }
  
    void setHead(Node head)
    {
        this.head = head;
    }
  
    Node getTail()
    {
        return tail;
    }
  
    void setTail(Node tail)
    {
        this.tail = tail;
    }
  
    // Function to replace Kth node from
    // beginning with Kth node from end
    void swapNode(Node headReference,
                         Node tailReference, int k)
    {
  
        // If K is 1, then the first node
        // has to be swapped with the
        // last node in the doubly linked list
        if (k == 1) {
            swapFirstAndLast(headReference,
                             tailReference);
            return;
        }
  
        // If k is N, then the last node
        // has to be swapped with the
        // first node in the doubly linked list
        int nodeCount = getCount(headReference);
        if (k == nodeCount) {
            swapFirstAndLast(headReference,
                             tailReference);
            return;
        }
  
        // If the Kth node from
        // the beginning and Kth node
        // from the ending are same
        if (2 * k - 1 == nodeCount) {
            return;
        }
  
        // fNode represents Kth node
        // from the beginning
        Node fNode = headReference;
        for (int i = 1; i < k; i++) {
            fNode = fNode.getNext();
        }
        Node fNodePrevious = fNode.getPrevious();
        Node fNodeNext = fNode.getNext();
  
        // sNode represents Kth node
        // from the ending
        Node sNode = tailReference;
        for (int i = 1; i < k; i++) {
            sNode = sNode.getPrevious();
        }
  
        Node sNodePrevious = sNode.getPrevious();
        Node sNodeNext = sNode.getNext();
  
        // Checking if any of the pointers is null
        // and interchanging the pointers
        if (fNodePrevious != null && sNode != null) {
  
            fNodePrevious.setNext(sNode);
            sNode.setPrevious(fNodePrevious);
            sNode.setNext(fNodeNext);
            fNodeNext.setPrevious(sNode);
        }
        if (sNodePrevious != null && sNodeNext != null) {
  
            sNodeNext.setPrevious(fNode);
            fNode.setNext(sNodeNext);
            sNodePrevious.setNext(fNode);
            fNode.setPrevious(sNodePrevious);
        }
    }
  
    // Function to swap the first and
    // last node in the doubly linked list
    private void swapFirstAndLast(
        Node headReference,
        Node tailReference)
    {
        Node headRef = headReference;
        Node tailRef = tailReference;
  
        headReference
            = headReference.getNext();
        tailReference
            = tailReference.getPrevious();
  
        tailReference.setNext(headRef);
        headRef.setPrevious(tailReference);
        headRef.setNext(null);
        this.setTail(tailReference.getNext());
  
        headReference.setPrevious(tailRef);
        tailRef.setNext(headReference);
        tailRef.setPrevious(null);
        this.setHead(headReference
                         .getPrevious());
    }
  
    // Function to return the number of nodes
    // in the linked list
    private int getCount(Node headReference)
    {
        int nodeCount = 0;
        while (headReference != null) {
            nodeCount++;
            headReference = headReference
                                .getNext();
        }
        return nodeCount;
    }
  
    // Function to print the Linked List
    void printList(Node headReference)
    {
        if (headReference == null) {
            Console.WriteLine(
                "Doubly linked list is empty");
            return;
        }
        else {
            while (headReference != null) {
                Console.Write(
                    headReference.getData()
                    + " ");
                headReference
                    = headReference.getNext();
            }
        }
    }
  
    // Function to insert a node at
    // the end of the doubly linked list
    void Push(int data)
    {
        Node newNode
            = new Node(data, null, null);
  
        if (head == null) {
            head = tail = newNode;
        }
        else {
            tail.setNext(newNode);
            newNode.setPrevious(tail);
            tail = newNode;
        }
    }
  
    // Driver code
    public static void Main(String[] args)
    {
  
        // Creating an object for the class
        GFG list = new GFG();
  
        // Adding data to the linked list
        list.Push(1);
        list.Push(2);
        list.Push(3);
        list.Push(4);
        list.Push(5);     
             
        // Calling the function
        int K = 2;
        list.swapNode(list.getHead(),
                      list.getTail(), K);
        list.printList(list.getHead());
    }
}
 
// This code is contributed by 29AjayKumar


Java
//java program to swap Kth node from beginning with
//the Kth node from the end without using temporary
//node and without swapping the data
public class GFG {
    //head pointer for pointing to start of the linked list
    //last pointer for pointing to last node of the linked list
    Node head = null,last = null;
     
    //class Node
    class Node{
        int data;
        Node first,next;
        Node(int data){
            this.data = data;
            first = null;
            next = null;
        }
    }
     
    //function for inserting new node at the
    //end of the list using last pointer
    void AddLast(int data) {
        Node temp = new Node(data);
        if(head == null) {
            head = temp;
            last = temp;
        }
        else {
            last.next = temp;
            temp.first = last;
            last = temp;
        }
    }
     
    //function for printing the doubly linked list
    void printList() {
        Node p = head;
        while(p!=null) {
            System.out.print(p.data+"<->");
            p = p.next;
        }
        System.out.print("null");
        System.out.println();
    }
     
    //function for swapping Kth node from
    //beginning with Kth node from the end
    void swapKthNodes(int k) {
        int count = 1;
        Node p = head, q = last;
        //case 1: to swap the start and end nodes
        //case 1 figure
        if(k == 1) {
            q.first.next = p;
            p.first = q.first;
             
            q.next = p.next;
            p.next.first = q;
             
            //change these links to null to the break circular link
            p.next = null;
            q.first = null;
             
            head = q;
            last = p;
        }
        else {
            while(p!=null  &&  q!=null  &&  count


输出:

1 4 3 2 5

方法二:不交换元素,不使用临时节点。

方法:有3种情况可以交换节点。

  • 交换第一个和最后一个节点(k = 1)
  • 交换从头开始的普通第 K 个节点和从末尾开始的第 K 个节点。
  • 交换中间节点

情况 1:交换第一个和最后一个节点(k = 1)

脚步:

  1. 将列表作为循环链表
  2. 将第一个节点的前一个指针更改为最后一个节点(示例图中为 20)
  3. 将最后一个节点的下一个指针更改为最后一个节点。在这种情况下,它将是 60。
  4. 交换后,将头部作为第一个节点。
Consider p and q are the nodes which are to be swapped,
   
   head = q; //change head pointer to point to head node
   last = p; //change last pointer to point to last node

交换第一个和最后一个节点

情况2:交换从头开始的普通第K个节点和从结束开始的第K个节点。

脚步:

  1. 让我们考虑 K = 2。所以要交换或互换的节点是 20 和 50,如图所示。
  2. 使要交换的节点的 first 和 next 指针都指向前一个节点。为此,我们需要将先前节点的链接更改为指向要交换的节点之后的节点。
Consider the nodes to be swapped are p and q:
    
    //Change the link of the next pointer of the previous node to point to
    //the next node of to be swapped node.
    q.first.next = q.next;    
    p.first.next = p.next; // Same procedure for the other node
    
    //Make sure to change the previous/first pointer of the next node to 
    //point to the previous of to be swapped node.
    q.next.first = q.first;     
    p.next.first = p.first;
    
    //Both the first and next pointers points to the previous node as shown in the below figure.
    q.next = q.first;
    p.next = p.first;

3.交换一个待交换节点与另一个待交换节点的指针。 (第3步表示互换后的图)。

4. 对链接进行必要的更改以使其成为完整列表。

一般情况

案例3:交换中间节点

脚步:

  1. 这种情况与情况2相同,唯一的变化是,要交换的节点是中间节点。所以他们两个都在一起(并排)。
  2. 考虑 p 是要交换的第一个节点,q 是要交换的第二个节点。
  3. 将 p 上一个节点的 next 指针指向 q 的下一个节点。这一步是为了省略 p 和 q 节点。
  4. 同理,将q的下一个节点的第一个指针指向q的上一个节点。
  5. 更改 p 和 q 的链接,使两个节点都指向 p 的前一个节点(下图中的 step2)。
  6. 相应地建立 p 和 q 的链接,使节点交换位置。

交换中间节点

执行:

Java

//java program to swap Kth node from beginning with
//the Kth node from the end without using temporary
//node and without swapping the data
public class GFG {
    //head pointer for pointing to start of the linked list
    //last pointer for pointing to last node of the linked list
    Node head = null,last = null;
     
    //class Node
    class Node{
        int data;
        Node first,next;
        Node(int data){
            this.data = data;
            first = null;
            next = null;
        }
    }
     
    //function for inserting new node at the
    //end of the list using last pointer
    void AddLast(int data) {
        Node temp = new Node(data);
        if(head == null) {
            head = temp;
            last = temp;
        }
        else {
            last.next = temp;
            temp.first = last;
            last = temp;
        }
    }
     
    //function for printing the doubly linked list
    void printList() {
        Node p = head;
        while(p!=null) {
            System.out.print(p.data+"<->");
            p = p.next;
        }
        System.out.print("null");
        System.out.println();
    }
     
    //function for swapping Kth node from
    //beginning with Kth node from the end
    void swapKthNodes(int k) {
        int count = 1;
        Node p = head, q = last;
        //case 1: to swap the start and end nodes
        //case 1 figure
        if(k == 1) {
            q.first.next = p;
            p.first = q.first;
             
            q.next = p.next;
            p.next.first = q;
             
            //change these links to null to the break circular link
            p.next = null;
            q.first = null;
             
            head = q;
            last = p;
        }
        else {
            while(p!=null  &&  q!=null  &&  count
输出
Before swapping:
10<->20<->30<->40<->50<->60<->null

After swapping nodes for k = 1:
60<->20<->30<->40<->50<->10<->null

After swapping nodes for k = 2:
60<->50<->30<->40<->20<->10<->null

After swapping nodes for k = 3 (middle):
60<->50<->40<->30<->20<->10<->null

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live