1. 程式人生 > >Java程式碼實現列隊基本操作

Java程式碼實現列隊基本操作

Java實現列隊基本操作

佇列的定義:

佇列(Queue)是隻允許在一端進行插入,而在另一端進行刪除的運算受限的線性表。

(1)允許刪除的一端稱為隊頭(Front)。

(2)允許插入的一端稱為隊尾(Rear)。
(3)當佇列中沒有元素時稱為空佇列。
(4)佇列亦稱作先進先出(First In First Out)的線性表,簡稱為FIFO表。
   佇列的修改是依先進先出的原則進行的。新來的成員總是加入隊尾,每次離開的成員總是佇列頭上的(不允許中途離隊)。

佇列的儲存結構及實現

佇列的順序儲存結構

(1) 順序佇列的定義:

 佇列的順序儲存結構稱為順序佇列,順序佇列實際上是運算受限的順序表。

(2)順序佇列的表示:

和順序表一樣,順序佇列利用記憶體中一段連續的儲存空間來存放當前佇列中的元素。
由於佇列的隊頭和隊尾的位置是變化的,設定兩個指標front和rear分別指示隊頭元素和隊尾元素,它們的初值在佇列初始化時均應置為0。

 

(3)順序佇列的基本操作


入隊時:將新元素插入rear所指的位置的後一位。
出隊時:刪去front所指的元素,然後將front加1並返回被刪元素。

(4)順序表的溢位現象

 ①“下溢”現象
 當佇列為空時,做出隊運算產生的溢位現象。“下溢”是正常現象,常用作程式控制轉移的條件。

② "真上溢"現象
當佇列滿時,做進棧運算產生空間溢位的現象。“真上溢”是一種出錯狀態,應設法避免。

③ "假上溢"現象
由於入隊和出隊操作中,頭尾指標只增加不減小,致使被刪元素的空間永遠無法重新利用。當佇列中實際的元素個數遠遠小於記憶體中本分配的空間時,也可能由於尾指標已超越向量空間的上界而不能做入隊操作。該現象稱為"假上溢"現象。如下圖

 迴圈佇列:

 如上圖所示,這種頭尾相接的順序儲存結構稱為迴圈佇列(circular queue)。

迴圈佇列中需要注意的幾個重要問題:

①隊空的判定條件,隊空的條件是front=rear;

②隊滿的判定條件,(rear+1)%QueueSize=front。QueueSize為佇列初始空間大小。

下面分別實現順序列隊和迴圈列隊

順序列隊:

package ch03;
/**
 * 佇列類
 * @author 小明
 *
 */
public class MyQueue {
	//狄燦使用陣列
  private long[] arr;
  //有效資料大小
  private int elements;
  //隊頭
  private int front;
  //隊尾
  private int end;
  
  /**
   * 預設構造方法
   */
  public MyQueue(){
	  arr = new long[10];
	  elements =0;
	  front =0;
	  end =-1;
  }
  
  /**
   * 帶引數的構造方法
   */
  public MyQueue(int maxsize){
	  arr = new long[maxsize];
	  elements =0;
	  front =0;
	  end =-1;
  }
  
  /**
   * 新增資料,隊尾新增
   */
  public void insert(long value){
	  arr[++end] =value;
	  elements++;
  }
  
  /**
   * 刪除資料,隊頭刪除
   */
  public long remove(){
	  elements--;
	  return arr[front++];
  }
  
  /**
   * 檢視資料
   */
  public long peek(){
	  return arr[front];
  }
  
  /**
   * 判斷是否為空
   */
  public boolean isEmpty(){
	  return elements ==0;
  }
  
  public boolean isFull(){
	  return elements ==arr.length;
  }
}

package ch03;

public class TestMyQueue {
public static void main(String[] args) {
	MyQueue myQueue = new MyQueue();
	myQueue.insert(10);
	myQueue.insert(20);
	myQueue.insert(30);
	myQueue.insert(40);
	myQueue.insert(50);
	System.out.println(myQueue.peek());
	myQueue.remove();
	System.out.println(myQueue.peek());
	
	while (!myQueue.isEmpty()) {
		System.err.print(myQueue.remove() + " ");
	}
	System.out.println("***********************");
	myQueue.insert(23);
	myQueue.insert(24);
	myQueue.insert(25);
	myQueue.insert(26);
	myQueue.insert(27);
	myQueue.insert(28);
	System.out.println(myQueue.peek());
}
}

迴圈列隊:
package ch03;
/*
 * 列隊類
 */
public class MyCycleQueue {
	//底層使用陣列
	private long[] arr;
	//有效資料的大小
	private int elements;
	//隊頭
	private int front;
	//隊尾
	private int end;
	
	/**
	 * 預設構造方法
	 */
	public MyCycleQueue() {
		arr = new long[10];
		elements = 0;
		front = 0;
		end = -1;
	}
	
	/**
	 * 帶引數的構造方法,引數為陣列的大小
	 */
	public MyCycleQueue(int maxsize) {
		arr = new long[maxsize];
		elements = 0;
		front = 0;
		end = -1;
	}
	
	/**
	 * 新增資料,從隊尾插入
	 */
	public void insert(long value) {
		if(end == arr.length - 1) {
			end = -1;
		}
		arr[++end] = value;
		elements++;
	}
	
	/**
	 * 刪除資料,從隊頭刪除
	 */
	public long remove() {
		long value = arr[front++];
		if(front == arr.length) {
			front = 0;
		}
		elements--;
		return value;
	}
	
	/**
	 * 檢視資料,從隊頭檢視
	 */
	public long peek() {
		return arr[front];
	}
	
	/**
	 * 判斷是否為空
	 */
	public boolean isEmpty() {
		return elements == 0;
	}
	
	/**
	 * 判斷是否滿了
	 */
	public boolean isFull() {
		return elements == arr.length;
	}
}

package ch03;

public class TestMyCycleQueue {
public static void main(String[] args) {
	MyCycleQueue mq = new MyCycleQueue(4);
	mq.insert(23);
	mq.insert(45);
	mq.insert(13);
	mq.insert(1);
	
	System.out.println(mq.isFull());
	System.out.println(mq.isEmpty());
	
	System.out.println(mq.peek());
	System.out.println(mq.peek());
	
	while (!mq.isEmpty()) {
		System.err.print(mq.remove() + " ");
	}
	System.out.println("***********************");
	mq.insert(23);
	mq.insert(45);
	mq.insert(13);
	mq.insert(1);
	
	while (!mq.isEmpty()) {
		System.out.print(mq.remove() + " ");
	}
}
}