From Gossip@caterpillar

Algorithm Gossip: 佇列 - 使用Java 作物件封裝

說明

如果您使用C++或Java等支援物件導向的語言來實作佇列,您可以使用類別的方式來包括佇列的功能,將所有的佇列操作由堆疊物件來處理,一旦包裝完成,則使用佇列物件的時候,只要呼叫加入、刪除等方法,而無需處理佇列的front、rear或判斷是否為空等細節。

解法

使用C++與使用Java來作類別包裝其實是類似的,在這邊我們使用Java實作,因為它的語法看來較簡潔;Java雖然沒有指標,但可以使用參考(Reference)來達到鏈結的效果,一個節點的類別包裝方式如下:
class Node {
    private int data;   // 節點資料
    private Node next;  // 下一個節點位置

    public void setData(int data);  // 節點資料
    public void setNext(Node next);  // 下一個節點位置
    public int getData();  // 傳回節點資料
    public Node getNext();  // 傳回下一個節點位置
}
 
其中next是個物件參考名稱,它可以用來參考至(指向)下一個節點物件的記憶體位置,而佇列類別可以如下包裝:
class Queue {
    private Node front;
    private Node rear;
    private String name;  // 只是個名稱

    // 利用建構子建立佇列
    public Queue();
    public Queue(String name);

    // 插入資料至前端
    public void add(int data);

    // 顯示前端資料
    public void printFront();

    // 刪除前端資料
    public void del();

    // 列出佇列內容
    public void list();
}
 
利用物件導向來包裝資料結構,雖然在設計時需要花較多的心思,但設計完成之後,日後呼叫使用就簡單了,以後您只要注意主程式的邏輯設計就可以了。

實作

import java.io.*; 

// 節點
class Node {
private int data; // 節點資料
private Node next; // 下一個節點位置

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

public void setNext(Node next) {
this.next = next;
}

public int getData() {
return data;
}

public Node getNext() {
return next;
}
}

// 佇列
class Queue {
private Node front;
private Node rear;
private String name; // 只是個名稱

public Queue() {
this("list");
}

// 利用建構子建立佇列
public Queue(String name) {
this.name = name;
front = new Node();
front.setNext(null);
rear = front;
}

// 插入資料至頂端
public void add(int data) {
Node newNode = new Node();

if(front.getNext() == null)
front.setNext(newNode);

newNode.setData(data);
newNode.setNext(null);
rear.setNext(newNode);
rear = newNode;
}

// 顯示前端資料
public void printFront() {
if(front.getNext() == null)
System.out.print("\n佇列為空!");
else
System.out.print("\n頂端值:" +
front.getNext().getData());
}

// 刪除前端資料
public void del() {
Node tmpNode;

if(front.getNext() == null) {
System.out.print("\n佇列已空!");
return;
}

tmpNode = front.getNext();
front.setNext(tmpNode.getNext());
tmpNode = null;
}

// 列出佇列內容
public void list() {
Node tmpNode;

tmpNode = front.getNext();

System.out.print("\n佇列內容:");
while(tmpNode != null) {
System.out.print(tmpNode.getData() + " ");
tmpNode = tmpNode.getNext();
}
}
}

public class Queueshow {
public static void main(String[] args)
throws IOException {
int input, select;
BufferedReader buf;
buf = new BufferedReader(
new InputStreamReader(System.in));

Queue q1 = new Queue("佇列測試");

while(true) {
System.out.print("\n\n請輸入選項(-1結束):");
System.out.print("\n(1)插入值至佇列");
System.out.print("\n(2)顯示佇列前端");
System.out.print("\n(3)刪除前端值");
System.out.print("\n(4)顯示所有內容");
System.out.print("\n$c>");

select = Integer.parseInt(buf.readLine());

if(select == -1)
break;

switch(select) {
case 1:
System.out.print("\n輸入值:");
input = Integer.parseInt(buf.readLine());
q1.add(input);
break;
case 2:
q1.printFront();
break;
case 3:
q1.del();
break;
case 4:
q1.list();
break;
default:
System.out.print("\n選項錯誤!");
}
}

System.out.println("");
}
}