【问题标题】:How to swap neighbouring nodes in a linked list如何交换链表中的相邻节点
【发布时间】:2021-08-05 13:34:02
【问题描述】:

我是编程新手,刚刚学习链表,我正在尝试交换列表中的相邻节点。例如:

input 1 2 3 4 5 6 
output 2 1 4 3 6 5

我找到了交换数据​​的解决方案,并尝试将其调整为交换节点,但我无法使其正常运行。有任何想法吗?一旦我启动pairWiseSwap,它似乎只是循环,见第三块。

    // Java program to pairwise swap elements of a linked list
class LinkedList {
    Node head; // head of list

    /* Linked list Node*/
    class Node {
        int data;
        Node next;
        Node(int d)
        {
            data = d;
            next = null;
        }
    }

     public void pairWiseSwap()
    {
        Node temp = head;
        Node swap;


        /* Traverse only till there are atleast 2 nodes left */
        while (temp != null && temp.next != null) {

            /*
            int k = temp.data;
            temp.data = temp.next.data;
            temp.next.data = k;
            temp = temp.next.next;
            */

            // just loops 
            swap = temp;
            temp = temp.next;
            temp.next = swap;
            temp = temp.next.next;

        }
    }

    /* Utility functions */

    /* Inserts a new Node at front of the list. */
    public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                  Put in the data*/
        Node new_node = new Node(new_data);

        /* 3. Make next of new Node as head */
        new_node.next = head;

        /* 4. Move the head to point to new Node */
        head = new_node;
    }

    /* Function to print linked list */
    void printList()
    {
        Node temp = head;
        while (temp != null) {
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
        System.out.println();
    }

    /* Driver program to test above functions */
    public static void main(String args[])
    {
        LinkedList llist = new LinkedList();

        /* Created Linked List 1->2->3->4->5 */
        llist.push(5);
        llist.push(4);
        llist.push(3);
        llist.push(2);
        llist.push(1);

        System.out.println("Linked List before calling pairWiseSwap() ");
        llist.printList();

        llist.pairWiseSwap();

        System.out.println("Linked List after calling pairWiseSwap() ");
        llist.printList();
    }
}

【问题讨论】:

    标签: java algorithm linked-list swap


    【解决方案1】:

    “在纸上”画出来会有帮助。我建议使用三个引用:prevcurrnext,它们在列表中相互跟随:

    public void pairWiseSwap()
    {
        if (head == null || head.next == null) {
            return;
        }
        Node prev = null;
        Node curr = head;
        Node next;
        head = head.next;
        while (curr != null && curr.next != null) {
            next = curr.next;
            if (prev != null) {
                prev.next = next;  // Link the previously swapped pair to the next pair
            }
            prev = curr;
            curr = next;
            next = curr.next;   // Save curr.next before changing it
            curr.next = prev;
            curr = next;
        }
        if (prev != null) {
            prev.next = curr;
        }
    }
    

    【讨论】:

      【解决方案2】:

      您也可以考虑递归解决方案。

      public void pairWiseSwap()
      {
          head = swapPair(head);      
      }
      
      private Node swapPair(Node curr)
      {
          if(curr == null || curr.next == null) return curr;
          
          Node next = curr.next;  
          curr.next = next.next;
          next.next = curr;
      
          curr.next = swapPair(curr.next);
          
          return next;
      }
      

      【讨论】:

        【解决方案3】:

        您可以使用通用代码序列来交换任意一对节点,无论是否相邻。首先交换指向两个节点的内容,然后交换节点中的指针。假设你想交换 b 和 d:

        non-adjacent nodes:
        a -> b -> c -> d -> e
        swap a.next and c.next     a -> d ... c -> b
        swap b.next and d.next     b -> e ... d -> c
                                   a -> d -> c -> b -> e
        
        adjacent nodes:
        a -> b -> d -> e
        swap a.next and b.next     a -> d ... b -> b
        swap b.next and d.next     b -> e ... d -> b
                                   a -> d -> b -> e
        

        如果有一个虚拟头节点不是实际列表的一部分,那么您不需要特殊代码来处理将第一个节点与另一个节点交换。对于上面的例子,a 可以是虚拟头节点,而实际的初始列表将以 b 开头。

        【讨论】:

          【解决方案4】:

          一种方法是操作对节点的引用。

          Node pf; // reference to first node in sequence pointing to Node a
          // Node a and Node b are adjacent nodes.
          
          pf -> a -> b -> rest of list
          
          a.next = b.next; // a -> rest of list
          b.next = a;      // b -> a
          pf.next = b;     // pf -> b
          // so now 
          pf -> b -> a -> rest of list
          

          当某些next 引用可能为空时,也可能需要考虑边缘情况。所以用边界情况进行测试,以确保无论你是哪两个相邻节点都可以正常工作"swapping."

          如果你在你的类声明中使用泛型,你可以适应任何类型。

          class LinkedList<T> {
              Node head; // head of list
          
              /* Linked list Node*/
              class Node {
                  T data;
                  Node next;
                  Node(T d)
                  {
                      data = d;
                      next = null;
                  }
              }
              // rest of class
          

          【讨论】:

          • 你赚钱了 :) 双击 :D
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多