java連結串列應用--基於連結串列實現佇列詳解(尾指標操作)
本文例項講述了java基於連結串列實現佇列。分享給大家供大家參考,具體如下:
在開始棧的實現之前,我們再來看看關於連結串列的只在頭部進行的增加、刪除、查詢操作,時間複雜度均為O(1)。
一、連結串列改進分析
對於佇列這種資料結構,需要線上性結構的一端插入元素,另外一端刪除元素。因此此時基於連結串列來實現佇列,則有一端的時間複雜度為O(n)。因此我們不能使用之前已經實現的連結串列結構,我們需要改進我們的連結串列。思路如下:
1.參考在連結串列頭部刪除、增加元素的時間複雜度為O(1)的思路,我們在連結串列的尾部設立一個Node型的變數tail來記錄連結串列的尾部在哪,此時再head端和tail端新增元素都是及其簡單的,在head端刪除元素也是及其簡單的,但對於在tail端刪除元素時,是無法在時間複雜度為O(1)的情況進行的,也就是從tail端刪除元素時不容易的。
2.只在頭部head刪除元素(隊首),在尾部tail端新增元素(隊尾)。
3.由於在基於連結串列實現佇列時不涉及到操作連結串列中間元素,此時我們改進的連結串列中,不在使用虛擬頭節,因此也就可能造成在沒有虛擬頭節點的情況下,連結串列為空。
二、連結串列改進程式碼
前言,在寫本小節之前,我們已經實現了一個基於靜態陣列的佇列,轉到檢視。此處我們實現基於連結串列的佇列。
在實現基於靜態陣列的佇列的時候,我們已經新建了一個package,此時我們在該package下新建一個LinkedListQueue類,用來實現Queue介面,目錄結構為:
1.Queue介面程式碼
package Queue; public interface Queue<E> { //獲取佇列中元素個數 int getSize(); //佇列中元素是否為空 boolean isEmpty(); //入佇列 void enqueue(E e); //出佇列 public E dequeue(); //獲取隊首元素 public E getFront(); }
2.LinkedListQueue類
package Queue; public class LinkedListQueue<E> implements Queue<E> { //將Node節點設計成私有的類中類 private class Node<E> { public E e; public Node next; //兩個引數的建構函式 public Node(E e,Node next) { this.e = e; this.next = next; } //一個引數的建構函式 public Node(E e) { this.e = e; this.next = null; } //無參建構函式 public Node() { this(null,null); } @Override public String toString() { return e.toString(); } } private Node<E> head,tail; private int size; //顯示初始化 public LinkedListQueue() { head = null; tail = null; size = 0; } //獲取佇列中節點個數 @Override public int getSize() { return size; } //佇列中是否為空 @Override public boolean isEmpty() { return size == 0; } //連結串列尾部進隊操作 @Override public void enqueue(E e) { if (tail == null) { tail = new Node(e); head = tail; } else { tail.next = new Node(e); tail = tail.next; } size++; } //連結串列頭部出隊操作 @Override public E dequeue() { if (isEmpty()) { throw new IllegalArgumentException("連結串列為空"); } Node<E> retNode = head; head = head.next; retNode.next = null; if (head == null) {//當連結串列只有一個元素時 tail = null; } size--; return retNode.e; } //獲取隊首元素 @Override public E getFront() { if (isEmpty()) { throw new IllegalArgumentException("連結串列為空"); } return head.e; } //為了便於測試,重寫object類toString()方法 @Override public String toString() { StringBuilder res = new StringBuilder(); res.append("Queue: front "); Node<E> cur = head; while (cur != null) { res.append(cur + "->"); cur = cur.next; } res.append("NULL tail"); return res.toString(); } }
3.為了便於測試,在LinkedListQueue類中新增一個main函式
//測試用例 public static void main(String[] args) { LinkedListQueue<Integer> queue = new LinkedListQueue<Integer>(); for (int i = 0; i < 10; i++) { queue.enqueue(i); System.out.println(queue); if (i % 3 == 2) {//每新增3個元素出佇列一個 queue.dequeue(); System.out.println(queue); } } }
4.結果為
結果分析:每進隊3個元素出佇列一個。
關於本小節,若您覺得還行、還過得去,記得給個推薦哦~,謝謝!!
本節原始碼 https://github.com/FelixBin/dataStructure/blob/master/src/Queue/LinkedListQueue.java
更多關於java演算法相關內容感興趣的讀者可檢視本站專題:《Java資料結構與演算法教程》、《Java操作DOM節點技巧總結》、《Java檔案與目錄操作技巧彙總》和《Java快取操作技巧彙總》
希望本文所述對大家java程式設計有所幫助。