學習筆記:資料結構棧和佇列
阿新 • • 發佈:2021-08-01
目錄
一、棧和佇列的共同點
棧和佇列主要作為程式設計師構思演算法的工具,不是完全的資料儲存工具,生命週期比持久型的資料結構短,只有程式執行操作期間才被建立,程式執行完成,就會銷燬。
特性是受限訪問,即不能像陣列那樣直接通過下標訪問元素,也不能像連結串列那樣順序遍歷訪問資料項,特定時刻只能有一個元素被訪問或刪除。
二、棧
1.特性
棧只允許訪問一個數據項:最後插入的資料項。只有移除這個資料項才能訪問倒數第二個被插入的資料項。
2.陣列實現棧
簡單的實現一下棧(用陣列),建立、入棧、出棧、檢視棧頂等方法。
public class ArrayStack { //底層是陣列,建立時要宣告陣列大小 int[] array; int maxSize = 10; //維護一個指標訪問棧頂元素,陣列就是下標數字 int top; public ArrayStack() { array = new int[maxSize]; top = -1; } public ArrayStack(int maxSize) { this.maxSize = maxSize; array = new int[maxSize]; top = -1; } //判斷是否空棧 public boolean isEmpty() { return top == -1; } //判斷是否滿棧 public boolean isFull() { return top == this.maxSize - 1; } //入棧 public void push(int data) { if (!isFull()){ array[++top] = data; } } //出棧,返回棧頂元素 public int pop() { if (!isEmpty()) { return array[top--]; } return 0; } //檢視棧頂元素 public int peek() { return array[top]; } }
測試一下:
public class StackTest { @Test public void testArrayStack() { ArrayStack stack = new ArrayStack(10); //入棧 stack.push(14); stack.push(23); stack.push(65); stack.push(12); //出棧 System.out.println("出棧元素: "+ stack.pop()); System.out.println("出棧元素: "+ stack.pop()); //檢視棧頂元素 System.out.println("棧頂元素: "+ stack.peek()); } }
執行結果:
出棧元素: 12
出棧元素: 65
棧頂元素: 23
push()
入棧方法中將top值加一,指向原來資料項頂端上面的一個位置,並在這位置上儲存一個數據項。
pop()
出棧方法返回top標識的資料項,然後再減一。儘管資料項仍在陣列中,但是不能訪問了,直到新元素壓入棧中覆蓋這個資料項
peek()
就是訪問top指向的資料項,不修改棧。
3.棧的效率
入棧和出棧時間複雜度O(1);
二、佇列
1.概述
佇列也是一種資料結構,和棧類似,不過佇列中的第一個插入的元素會最先被移除。
佇列的常見操作時建立和入隊、出隊、檢視隊首方法。
public class ArrayQueue {
//陣列實現佇列,需要宣告大小
int maxSize = 10;
int[] array;
//宣告隊頭指標
int front;
//宣告隊尾指標
int near;
//記錄元素個數
int num;
public ArrayQueue() {
array = new int[maxSize];
front = 0;
near = -1;
num = 0;
}
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
front = 0;
near = -1;
num = 0;
}
//判斷非空
public boolean isEmpty() {
return num == 0;
}
//判斷是否滿
public boolean isFull() {
return num == maxSize;
}
//入隊
public void insert(int data) {
if (!isFull()) {
if (near == maxSize - 1) { //迴圈佇列
near = -1;
}
array[++near] = data;
num++;
}
}
//出隊
public int remove() {
if (isEmpty()) {
return -1;
}
int temp = array[front];
if (front == maxSize -1) {
front = -1;
}
front++;
num--;
return temp;
}
//檢視隊首元素
public int peekFront() {
return array[front];
}
//佇列資料項數量
public int size() {
return num;
}
}
測試程式碼:
public class QueueTest {
@Test
public void testArrayQueue() {
ArrayQueue arrayQueue = new ArrayQueue();
//測試入隊方法
arrayQueue.insert(23);
arrayQueue.insert(230);
arrayQueue.insert(2300);
arrayQueue.insert(23000);
//檢視隊首元素
System.out.println("隊首元素: "+arrayQueue.peekFront());;
//測試出隊方法
System.out.println("出隊元素: "+arrayQueue.remove());
System.out.println("隊首元素: "+arrayQueue.peekFront());;
System.out.println("出隊元素: "+arrayQueue.remove());
System.out.println("隊首元素: "+arrayQueue.peekFront());;
System.out.println("元素個數:" +arrayQueue.size());
}
}
執行結果:
隊首元素: 23
出隊元素: 23
隊首元素: 230
出隊元素: 230
隊首元素: 2300
元素個數:2
2.佇列的效率
佇列效率和棧一樣,入隊和出隊時間複雜度都是O(1);
3.優先順序佇列
優先順序和佇列和普通佇列一樣,也是有隊首和隊尾,不過優先順序佇列資料項按照關鍵字的值有序。
public class PriorityQueue {
//陣列實現佇列,需要宣告大小
int maxSize = 10;
int[] array;
//記錄元素個數
int num;
public PriorityQueue() {
array = new int[maxSize];
num = 0;
}
public PriorityQueue(int maxSize) {
this.maxSize = maxSize;
array = new int[maxSize];
num = 0;
}
//判斷非空
public boolean isEmpty() {
return num == 0;
}
//判斷是否滿
public boolean isFull() {
return num == maxSize;
}
//入隊
public boolean insert(int data) {
if (isFull()) {
return false;
}
if (isEmpty()) {
array[num++] = data;
return true;
} else {
int i;
for ( i = num - 1; i >= 0; i --) {
if (array[i] < data) {
array[i+1] = array[i];
} else {
break;
}
}
array[i+1] = data;
num++;
return true;
}
}
//出隊
public int remove() {
if (isEmpty()) {
return -1;
} else {
return array[--num];
}
}
//檢視優先順序最小的元素
public int peekMin() {
return array[num-1];
}
//佇列資料項數量
public int size() {
return num;
}
}
測試程式碼:
@Test
public void testPriorityQueue() {
PriorityQueue priorityQueue = new PriorityQueue();
//入隊
priorityQueue.insert(78);
priorityQueue.insert(32);
priorityQueue.insert(2);
priorityQueue.insert(788);
System.out.println("元素個數:" + priorityQueue.size());
//出隊
System.out.println("出隊元素: "+ priorityQueue.remove());
System.out.println("優先順序最小的元素: "+ priorityQueue.peekMin());
System.out.println("出隊元素: "+ priorityQueue.remove());
System.out.println("優先順序最小的元素: "+ priorityQueue.peekMin());
System.out.println("元素個數:" + priorityQueue.size());
//檢視隊尾元素
System.out.println("優先順序最小的元素: "+ priorityQueue.peekMin());
}
執行結果:
元素個數:4
出隊元素: 2
優先順序最小的元素: 32
出隊元素: 32
優先順序最小的元素: 78
元素個數:2
優先順序最小的元素: 78
優先順序佇列的效率:插入的時間複雜度是O(n),刪除的效率是O(1)