如何在Java中反轉單連結串列?

jdon發表於2019-01-27

在本文中,我將向您展示如何在沒有遞迴的情況下在Java中反轉單個連結串列。單連結串列,也稱為連結串列,是一組節點,只能在一個方向上遍歷,例如向前。連結串列中的每個節點都包含兩個內容,一個資料和指向列表中下一個節點的指標。為了反轉連結串列,我們需要遍歷列表,在每一步我們都需要反轉連結,例如在第一次迭代之後,head將指向null,而next元素將指向head。在到達連結串列尾部時遍歷結束時,尾部將指向第二個最後一個元素,它將成為一個新頭,因為您可以遍歷此節點中的所有元素。

因為我們不能使用java.util.LinkedList來演示這個例子,因為它是一個雙向連結串列。在雙向連結串列中,您可以在兩個方向上進行遍歷,即向前和向後遍歷,因為每個節點都包含對前一個節點和下一個節點的引用。請參閱Thomas H. Cormen的“演算法簡介”中的良好資料結構和演算法手冊,以瞭解有關連結串列資料結構的更多資訊。

對於這個例子,我建立了我們自己的單連結串列類。與java.util.LinkedList類似,它還包含一個巢狀的靜態類Node,它表示連結列表的節點。它包含一個整數屬性來儲存資料部分,另一個Node引用指向列表中的下一個。如果要建立通用連結列表,則應將int替換為泛型型別T,如此處所示。

為了證明我們的反向方法有效,我們不僅要建立連結串列,還要填充連結串列。為了填充,我們需要在單連結串列上實現add()方法。你有兩個選擇,要麼在頭部或尾部新增元素,要新增元素是很容易的,因為它不需要遍歷直到結束但是如果你想建立一個包含按順序排列元素的列表新增然後我們需要在連結串列的末尾新增節點。

我還建立了一個print()方法來列印單個連結串列的所有節點,用空格分隔。此方法非常有用,可以證明我們的反向方法是否正常工作,因為您可以在反轉之前和之後列印連結串列。

無遞迴單連結串列的Java程式

這是我們的示例程式,演示如何在Java中反轉連結串列。為了逆轉,我首先建立了一個名為singlylinkedlist的類,它表示一個連結串列資料結構。我進一步實現了add()和print()方法,將元素新增到連結列表中,並按向前順序列印。

反向連結列表的邏輯封裝在reverse()方法中。它從頭部到尾部遍歷連結列表,並在每個步驟中反轉連結,例如,每個節點而不是指向開始指向上一個節點的下一個元素,這樣,當到達最後一個元素時,整個連結列表將反轉,然後該元素將成為連結列表的新頭部。

package test;

/**
 * Java Program to reverse a singly list without using recursion.
 */
public class LinkedListProblem {

  public static void main(String[] args) {

    // creating a singly linked list
    SinglyLinkedList.Node head = new SinglyLinkedList.Node(1);
    SinglyLinkedList linkedlist = new SinglyLinkedList(head);

    // adding node into singly linked list
    linkedlist.add(new SinglyLinkedList.Node(2));
    linkedlist.add(new SinglyLinkedList.Node(3));
    // printing a singly linked list
    linkedlist.print();

    // reversing the singly linked list
    linkedlist.reverse();

    // printing the singly linked list again
    linkedlist.print();

  }

}
/**
 * A class to represent singly list in Java
 * 
 * @author WINDOWS 8
 *
 */
class SinglyLinkedList {

  static class Node {

    private int data;
    private Node next;

    public Node(int data) {
      this.data = data;
    }

    public int data() {
      return data;
    }

    public Node next() {
      return next;
    }
  }

  private Node head;

  public SinglyLinkedList(Node head) {
    this.head = head;
  }

  /**
   * Java method to add an element to linked list
   * @param node
   */
  public void add(Node node) {
    Node current = head;
    while (current != null) {
      if (current.next == null) {
        current.next = node;
        break;
      }
      current = current.next;
    }
  }

  /**
   * Java method to print a singly linked list
   */
  public void print() {
    Node node = head;
    while (node != null) {
      System.out.print(node.data() + " ");
      node = node.next();
    }
    System.out.println("");
  }

  /**
   * Java method to reverse a linked list without recursion
   */
  public void reverse() {
    Node pointer = head;
    Node previous = null, current = null;

    while (pointer != null) {
      current = pointer;
      pointer = pointer.next;

      // reverse the link
      current.next = previous;
      previous = current;
      head = current;
    }

  }
}
Output
1 2 3 
3 2 1 


您可以看到連結列表已反轉,前面的1是第一個元素,現在是最後一個元素,而3是連結列表或頭的第一個元素。

所有這些都是關於如何在Java中不使用遞迴來反轉單連結串列。這個解決方案中沒有使用遞迴,而是使用迭代。您可以看到reverse()方法中的while迴圈。
 

相關文章