蘋果已禁止 Android TV 使用者購買 Apple TV App 上的內容,訊息稱為了防止谷歌抽佣金
阿新 • • 發佈:2022-03-23
佇列 (先入先出原則)
-
如果說連結串列和順序表是對資料的存取位置的組織方式,那麼佇列就是一種對於存取方式限制的組織方式。換一種方式描述的話就是,佇列既可以採用連結串列來表示,也可以採用陣列(線性表)來表示,我們限制的是對於存放資料的存取方式。
-
出從隊首出,入插入隊尾
-
佇列:只允許在一端進行插入操作,而另一端進行刪除操作的線性表。
-
空佇列:不含任何資料元素的佇列。
-
允許插入(也稱入隊、進隊)的一端稱為隊尾,允許刪除(也稱出隊)的一端稱為隊頭。
例題:
銀行排隊問題, 銀行只有兩個接待視窗,VIP 視窗和普通視窗,VIP 使用者進入 VIP 使用者視窗,剩下的進入普通視窗排隊。
現在有以下輸入:
第一行 M 次操作(M<1000) 第二行 到 第M+1行 輸入操作 格式: IN name V OUT V IN name2 N OUT N 即 第一個字串為操作 是IN進入排隊和OUT 出隊 IN 排隊 跟著兩個字串為姓名和許可權V或N OUT 為出隊即完成操作,V和N代表那個視窗完成了操作 輸出:M次操作後V佇列和N佇列中姓名,先輸出V佇列後輸出N佇列。 樣例: 輸入: 5 IN xiaoming N IN Adel V IN laozhao N OUT N IN CLZ V 輸出: Adel CLZ laozhao
分析思路:
- 第一步,建立兩個佇列,以及兩個佇列的首尾指標
- 第二步,我們要寫入隊函式:按照佇列的定義使用尾指標模擬即可;設定 Type 位來表示是哪一個佇列;Type為V,那麼Name進入V佇列;Type為N,那麼Name進入N佇列;
- 第三步,我們要寫出隊函式:按照佇列的定義使用頭指標模擬即可;仍需設定 Type 位來表示是哪一個佇列
- 第四步,寫出獲取隊頭元素的程式碼,佇列我們只關心誰排在第一個;按照佇列的定義使用頭指標模擬即可;仍需設定 Type 位來表示是哪一個佇列;
- 主函式程式碼:
輸入M 迴圈M次: 輸入操作符OP OP為IN,則輸入name和Type OP為Out,則輸入Type 根據執行OP執行in或out操作 若佇列V不為空,執行以下操作: 輸出隊首元素,隊首出隊 直到為空為止 若佇列N不為空,執行以下操作: 輸出隊首元素,隊首出隊 直到為空為止
程式碼實現(用陣列模擬佇列):
package 佇列;
import java.util.Scanner;
public class Quque_01 {
//1. 建立兩個佇列,以及兩個佇列的首尾指標
static String Vqueue[] = new String[1000]; // V佇列
static int Vhead = 0; // 首指標
static int Vtail = 0; // 尾指標
static String Nqueue[] = new String[1000]; // N佇列
static int Nhead = 0; // 首指標
static int Ntail = 0; // 尾指標
//2.入隊函式: 尾指標模擬 設定 Type 位來表示是哪一個佇列
static void in(String name,String type) {
if(type.contains("V")) {
Vqueue[Vtail++] = name;
}
else {
Nqueue[Ntail++] = name;
}
}
//3.出隊函式:頭指標模擬 設定 Type 位來表示是哪一個佇列
static boolean out(String type) {
if(type.contains("V")) {
//先判斷佇列是否為空 為空的條件就是首尾指標相等
if(Vhead == Vtail) {
return false;
}
else {
Vhead++;
return true;
}
}
else {
if(Nhead == Ntail) {
return false;
}
else {
Nhead++;
return true;
}
}
}
//4.獲取隊頭元素
static String getHead(String type) {
if(type.contains("V")) {
return Vqueue[Vhead];
}
else {
return Nqueue[Nhead];
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//輸入操作次數
int m = scanner.nextInt();
while(m>0) {
m--;
// 輸入操作符 若為IN,則輸入name和Type; 若為Out,則輸入Type
String opString = scanner.next();
if(opString.contains("IN")){
String name = scanner.next();
String type = scanner.next();
in(name, type);
}
else {
String type = scanner.next();
out(type);
}
}
//若佇列V不為空,輸出隊首元素,隊首出隊,直到為空為止
String v = getHead("V");
while(out("V")) {//此處顯示了出隊函式中的功能:判斷是否空 頭指標後移 以及返回型別是boolean
System.out.println(v);
v = getHead("V");//獲取下一個隊首元素
}
//若佇列N不為空,輸出隊首元素,隊首出隊,直到為空為止
String n= getHead("N");
while(out("N")) {
System.out.println(n);
n = getHead("N");
}
}
}
使用java中已經定義好的佇列資料結構(用陣列模擬是為了更好地瞭解佇列的實現原理,以後用到佇列時,直接呼叫Queue)
定義方式:
Queue<String> queue = new LinkedList<String>();
部分成員函式(包括繼承的):
add(): 增加一個元索,如果佇列已滿,則丟擲一個異常 |
---|
remove():移除並返回佇列頭部的元素,如果佇列為空,則丟擲一個異常 |
element():返回佇列頭部的元素,如果佇列為空,則丟擲一個異常 |
offer():新增一個元素並返回 true,如果佇列已滿,則返回 false |
put(): 新增一個元素, 如果佇列滿,則阻塞 |
take(): 移除並返回佇列頭部的元素,如果佇列為空,則阻塞 |
size(): 返回佇列長度。 |
peek(): 返回佇列頭部的元素,如果佇列為空,則返回 null |
poll(): 移除並返問佇列頭部的元素,如果佇列為空,則返回 null |
程式碼實現:
package 佇列;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Quque_02 {
// 1. 建立兩個佇列
static Queue<String> vqueue = new LinkedList<>();
static Queue<String> nqueue = new LinkedList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 輸入操作次數
int m = scanner.nextInt();
while (m > 0) {
m--;
// 輸入操作符 若為IN,則輸入name和Type; 若為Out,則輸入Type
String opString = scanner.next();
if (opString.contains("IN")) {
String name = scanner.next();
String type = scanner.next();
if (type.contains("V")) {
vqueue.offer(name);// offer():新增一個元素並返回 true,如果佇列已滿,則返回 false
} else {
nqueue.offer(name);
}
} else {
String type = scanner.next();
if (type.contains("V")) {
vqueue.poll();// poll(): 移除並返問佇列頭部的元素,如果佇列為空,則返回 null
} else {
nqueue.poll();
}
}
}
//輸出:
//若佇列V不為空,輸出隊首元素,隊首出隊,直到為空為止
while(vqueue.size()!=0) {
System.out.println(vqueue.poll());
}
//若佇列N不為空,輸出隊首元素,隊首出隊,直到為空為止
while(nqueue.size()!=0) {
System.out.println(nqueue.poll());
}
}
}