一、棧
一般而言,棧是一個線性表,其所有的插入和刪除均是限定在表的一端進行,允許插入和刪除的一端稱棧頂(Top),不允許插入和刪除的一端稱棧底(Bottom)
若給定一個棧S=(a1, a2,a3,…,an),則稱a1為棧底元素,an為棧頂元素,元素ai位於元素ai-1之上。棧中元素按a1, a2,a3,…,an 的次序進棧,如果從這個棧中取出所有的元素,則出棧次序為an, an-1,…,a1 。也就是說,棧中元素的進出是按後進先出的原則進行,這是棧結構的重要特徵。因此棧又稱為後進先出(LIFO—Last In First Out)表。
通常,對棧進行的運算主要有以下幾種:
(1) 往棧頂加入一個新元素,稱進棧;
(2) 刪除棧頂元素,稱退棧;
(3) 查看當前的棧頂元素,稱讀棧。
public class Stack { // 棧數組 long stackArr[]; // 棧的大小 int maxSize; // 棧的頂部 int top; // 初始化一個大小為size的棧 public Stack(int size) { maxSize = size; stackArr = new long[size]; top = -1; } // 出棧操作 public long pop() { return stackArr[top--]; } // 進棧操作 public void push(long value) { stackArr[++top] = value; } // 判斷棧是否為空白 public boolean isEmpty() { return top == -1; } // 判斷棧是否已滿 public boolean isFull() { return top == maxSize - 1; } // 取棧頂元素 public long peek() { return stackArr[top]; } public static void main(String[] args) { Stack stack = new Stack(10); while (!stack.isFull()) { long v = (long) (Math.random() * 100); stack.push(v); System.out.print(v + " "); } System.out.println(); while (!stack.isEmpty()) { long topValue = stack.pop(); System.out.print(topValue + " "); } System.out.println(); }}
輸出:
94 33 49 96 25 2 66 95 86 39
39 86 95 66 2 25 96 49 33 94
二、隊列
隊列(Queue)也是線性表的一種特殊情況,但它與棧不同,其所有的插入均限定在表的一端進行,而所有的刪除則限定在表的另一端進行。
允許插入的一端稱隊尾(Rear),允許刪除的一端稱隊頭(Front)。
隊列的結構特點是先進隊的元素先出隊。假設有隊列Q=(a1, a2,a3,…,an),則隊列Q中的元素是按a1, a2,a3,…,an的次序進隊,而第一個出隊的應該是a1,第二個出隊的應該是 a2,只有在ai-1出隊以後,ai才可以出隊(1≤i≤n)。因此,通常又把隊列叫做先進先出(FIFI—First In First Out)表。
關於隊列的運算主要包括以下幾種:
(1) 進隊(插入)把一個新元素添加在隊列的末尾;
(2) 出隊(刪除)撤去隊頭元素;
(3) 查看(讀隊頭)查看當前隊頭元素。
public class Queue { //隊列數組 private long queueArr[]; //隊列的前端下標 private int front; //隊列的尾端下標 private int rear; //隊列的大小 private int maxSize; //隊列中元素的個數 private int nItems; //初始化一個大小為size的隊列 public Queue(int size){ queueArr = new long[size]; maxSize = size; front = 0; rear = -1; nItems = 0; } //插入操作 public void insert(long value){ //隊列已滿 if(rear == maxSize-1) rear = -1; queueArr[++rear] = value; nItems++; } //刪除操作 public long remove(){ long temp = queueArr[front++]; if(front == maxSize) front = 0; nItems--; return temp; } //返回隊列第一個元素 public long peakFront(){ return queueArr[front]; } //判斷是否為空白 public boolean isEmpty(){ return nItems == 0; } //判斷是否已滿 public boolean isFull(){ return nItems == maxSize; } //返回隊列中元素的個數 public int size(){ return nItems; } public void print(){ for(int i = front;i < front+nItems;i++){ System.out.print(queueArr[i]+" "); } System.out.println(); } public static void main(String[] args) { Queue q = new Queue(10); while(!q.isFull()){ long value = (long)(Math.random()*100); q.insert(value); } q.print(); while(!q.isEmpty()){ q.remove(); q.print(); } System.out.println(q.isEmpty()); }}
輸出:
10 15 76 88 13 16 52 37 80 39
15 76 88 13 16 52 37 80 39
76 88 13 16 52 37 80 39
88 13 16 52 37 80 39
13 16 52 37 80 39
16 52 37 80 39
52 37 80 39
37 80 39
80 39
39
true
三、優先順序隊列
優先順序隊列(priority queue) 是0個或多個元素的集合,每個元素都有一個優先權,對優先順序隊列執行的操作有(1)尋找(2)插入一個新元素 (3)刪除 一般情況下,尋找操作用來搜尋優先權最大的元素,刪除操作用來刪除該元素 。對於優先權相同的元素,可按先進先出次序處理或按任意優先權進行。
優先順序隊列 是不同於先進先出隊列的另一種隊列。每次從隊列中取出的是具有最高優先權的元素。
public class PriorityQueue { private int nItems; private long pqArr[]; private int maxSize; public PriorityQueue(int size){ maxSize = size; pqArr = new long[size]; nItems = 0; } public void insert(long value){ int i; if(nItems == 0) pqArr[nItems++] = value; else{ for(i = nItems-1;i >= 0;i--){ if(value < pqArr[i]){ pqArr[i+1] = pqArr[i]; } else break; } pqArr[i+1] = value; nItems++; } } public long remove(){ return pqArr[--nItems]; } public boolean isEmpty(){ return nItems == 0; } public boolean isFull(){ return nItems == maxSize; } public void print(){ for(int i = 0;i < nItems;i++) System.out.print(pqArr[i]+" "); System.out.println(); } public static void main(String[] args) { PriorityQueue pq = new PriorityQueue(10); while(!pq.isFull()){ long value = (long)(Math.random()*100); pq.insert(value); } pq.print(); }}
輸出:
9 12 17 17 43 45 50 73 85 89
總結:
1. 棧、隊列和優先順序隊列是經常用於簡化某些程式操作的資料結構。
2. 在這些資料結構中,只有一個資料項目可以被訪問。
3. 棧允許訪問最後一個插入的資料項目。
4. 棧中重要的操作是在棧頂插入(壓入)一個資料項目,以及從棧頂移除(彈出)一個資料項目。
5. 隊列只允許訪問第一個插入的資料項目。
6. 隊列的重要操作是在隊尾插入資料項目和在隊頭移除資料項目。
7. 隊列可以實現為迴圈隊列,它基於數組,數組下標可以從數組末端迴繞到數組的開始位置。
8. 優先順序隊列允許訪問最小(或者有時是最大)的資料項目。
9. 優先順序隊列的重要操作是有序地插入新資料項目和移除關鍵字最小的資料項目。
11. 這些資料結構可以用數組實現,也可以用其他機制(例如鏈表)來實現。