如何在Java中一次性查詢Java中連結串列的中間元素

jdon發表於2019-01-26

如何在一次傳遞中找到LinkedList的中間元素?這是一個Java和非Java程式設計師面試時經常被問到的程式設計問題。這個問題類似於檢查迴文或計算階乘,有時也會要求編寫程式碼。為了回答這個問題,候選人必須熟悉LinkedList的資料結構,即在單個LinkedList的情況下,連結串列的每個節點都包含資料和指標,這是下一個連結串列的地址,而單個連結串列的最後一個元素指向空值。因為要找到連結列表的中間元素,您需要找到LinkedList的長度,它將元素計數到末尾,即直到找到連結列表的最後一個元素為止。這個資料結構面試問題有趣的是,你需要一次找到LinkedList的中間元素,而你不知道LinkedList的長度。這就是應試者邏輯能力測試的地方,不管他是否熟悉時空權衡等。

你仔細想想你可以透過使用兩個指標來解決這個問題,如何在Java中查詢單連結串列的長度。透過使用兩個指標,在每次迭代時遞增一個,在每次迭代時遞增另一個。當第一個指標指向連結列表的末尾時,第二個指標將指向連結列表的中間節點。

事實上,這兩個指標方法可以解決多個類似問題,例如如何在一次迭代中找到連結列表中最後一個的第三個元素或如何在連結列表中找到最後一個元素。在這個Java程式設計教程中,我們將看到一個Java程式,它在一次迭代中找到Linked List的中間元素。

Java程式在一次傳遞中查詢LinkedList的中間元素

如何在Java中找到連結串列的中間元素,以Java為例,用Java程式找到連結串列中間節點。記住,LyKeDLead類是我們的自定義類,不要把這個類與JavaUTL.LIKEDLIST混淆,它是Java中一個流行的集合類。在這個Java程式中,我們的類連結表代表一個連結串列資料結構,它包含節點的集合並具有頭部和尾部。每個節點包含資料和地址部分。LIKEDListTestC類的主要方法用於模擬問題,在其中建立連結串列並在其中新增了幾個元素,然後在Java中對它們進行迭代,以一次傳遞中找到連結列表的中間元素。

import test.LinkedList.Node;

/**
 * Java program to find middle element of linked list in one pass.
 * In order to find middle element of linked list we need to find length first
 * but since we can only traverse linked list one time, we will use two pointers
 * one which we will increment on each iteration while other which will be
 * incremented every second iteration. so when first pointer will point to the
 * end of linked list, second will be pointing to the middle element of linked list
 * @author
 */
public class LinkedListTest {
  
  
    public static void main(String args[]) {
        //creating LinkedList with 5 elements including head
      LinkedList linkedList = new LinkedList();
      LinkedList.Node head = linkedList.head();
      linkedList.add( new LinkedList.Node("1"));
      linkedList.add( new LinkedList.Node("2"));
      linkedList.add( new LinkedList.Node("3"));
      linkedList.add( new LinkedList.Node("4"));
    
      //finding middle element of LinkedList in single pass
      LinkedList.Node current = head;
      int length = 0;
      LinkedList.Node middle = head;
    
      while(current.next() != null){
          length++;
          if(length%2 ==0){
              middle = middle.next();
          }
          current = current.next();
      }
    
      if(length%2 == 1){
          middle = middle.next();
      }

      System.out.println("length of LinkedList: " + length);
      System.out.println("middle element of LinkedList : " + middle);
      
    } 
  
}

class LinkedList{
    private Node head;
    private Node tail;
  
    public LinkedList(){
        this.head = new Node("head");
        tail = head;
    }
  
    public Node head(){
        return head;
    }
  
    public void add(Node node){
        tail.next = node;
        tail = node;
    }
  
    public static class Node{
        private Node next;
        private String data;

        public Node(String data){
            this.data = data;
        }
      
        public String data() {
            return data;
        }

        public void setData(String data) {
            this.data = data;
        }

        public Node next() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
      
        public String toString(){
            return this.data;
        }
    }
}

Output:
length of LinkedList: 4
middle element of LinkedList : 2


這就是如何在一次傳遞中找到LinkedList的中間元素。  此處提到的用於查詢LinkedList的中間節點的技術也可用於從LinkedList中的Last或nth元素中找到第3個元素。

相關文章