Java 棧與隊列超詳細分析講解
一、棧(Stack)
1、什么是棧?
棧其實就是一種數(shù)據(jù)結(jié)構(gòu) - 先進后出(先入棧的數(shù)據(jù)后出來,最先入棧的數(shù)據(jù)會被壓入棧底)
什么是java虛擬機棧?
java虛擬機棧只是JVM當中的一塊內(nèi)存,該內(nèi)存一般用來存放 例如:局部變量當調(diào)用函數(shù)時,我們會為函數(shù)開辟一塊內(nèi)存,叫做 棧幀,在 java虛擬機棧中開辟,具體如下。
常見考點:不可能的出棧順序
這道題該怎么分析呢?
首先我們知道,出棧時拿到的第一個元素為4,那么4必須入棧,因為入棧的順序是 1 2 3 4 5 6,所以4要入棧,1 2 3 得先入棧。(通過后面分析得知,該出棧序列正確)
2、棧的常見方法
方法 | 作用 |
---|---|
E push(E item) | 放入元素 |
E pop() | 獲取棧頂元素并彈出 |
E peek() | 獲取棧頂元素 |
boolean isEmpty() | 判斷棧是否為空(父類Vector的方法) |
3、自己實現(xiàn)一個棧(底層用一個數(shù)組實現(xiàn))
public class MyStack { public int[] elem; public int usedSize; public MyStack() { this.elem = new int[4]; } // 放入元素 public void push(int val) { if(isFull()) { // 如果放滿了,二倍擴容 this.elem = Arrays.copyOf(elem,2 * elem.length); } this.elem[this.usedSize++] = val; } // 獲取棧頂元素并彈出 public int pop() { if (isEmpty()) { throw new RuntimeException("棧為空!"); } usedSize--; return elem[usedSize]; } // 獲取棧頂元素 public int peek() { if (isEmpty()) { throw new RuntimeException("棧為空!"); } return elem[usedSize-1]; } // 是否為空 public boolean isEmpty() { return usedSize == 0; } // 是否滿了 public boolean isFull() { return elem.length == usedSize; } }
二、隊列(Queue)
1、什么是隊列?
只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作的特殊線性表,隊列具有 - 先進先出。
入隊列:進行插入操作的一端稱為隊尾
出隊列:進行刪除操作的一端稱為隊頭
2、隊列的常見方法
// 普通隊列 Queue<Integer> queue = new LinkedList<>(); queue.offer(1);// 隊尾入 int top = queue.peek();// 獲取隊頭元素 queue.poll();// 彈出隊尾元素并返回 // 雙端隊列 Deque<Integer> deque = new LinkedList<>(); deque.offer(1);// 默認隊尾入 deque.offerFirst(2);// 隊頭入 deque.offerLast(3);// 隊尾入 deque.peekFirst();// 獲取隊頭元素 deque.peekLast();// 獲取隊尾元素 deque.pollFirst();// 彈出隊頭元素并返回 deque.pollLast();// 彈出隊尾元素并返回
3、隊列的實現(xiàn)(單鏈表實現(xiàn))
/** * 每個節(jié)點 */ class Node{ public int val; public Node next; public Node(int val) { this.val = val; } } public class MyQueue { public Node head; public Node tail; /** * 插入元素 -- 尾插法 * @param val */ public void offer(int val) { Node node = new Node(val); if (head == null) { head = node; tail = node; }else { tail.next = node; tail = tail.next; } } /** * 出隊列 */ public int poll() { if(isEmpty()) { throw new RuntimeException("隊列為空!"); } int val = head.val; head = head.next; return val; } /** * 獲取隊頭元素 */ public int peek() { if(isEmpty()) { throw new RuntimeException("隊列為空!"); } return head.val; } // 隊列是否為空 public boolean isEmpty() { return head == null; } }
4、循環(huán)隊列
當考慮用數(shù)組來實現(xiàn)一個隊列, 很容易想到以下結(jié)構(gòu):
當我們連續(xù)從該隊頭中彈出元素時,就可以發(fā)現(xiàn)問題了
可以看到此時數(shù)組并沒有滿,但是當我們再次插入元素時,隊尾卻插入不了了,這時候我們可以想到將該數(shù)組看成是循環(huán)的數(shù)組,結(jié)構(gòu)如下。
可以看出,當 front 和 rear 相遇時,隊列可能的情況有兩種,要么為空,要么是滿的狀態(tài)。那么隊列什么時候為空,什么時候是滿的呢?
我們有兩種方法:
1、設置usedSize 當usedSize和數(shù)組長度相等時為滿,等于0 則為空。
2、設置標志位 設 flag = true,每放一個元素,將 flag 置為 false,每有一個元素出隊列,則將 flag 置為 true。當 front 和 rear 相遇時,flag為 true 則是空的,反之則是滿的。
public class MyCircularQueue { public int[] elem; public int front;// 隊頭下標 public int rear;// 隊尾下標 boolean flag = true;// 是否為空 public MyCircularQueue(int k) { elem = new int[k]; } // 向循環(huán)隊列插入一個元素。如果成功插入則返回真。 public boolean enQueue(int value) { if (isFull()) { return false; // throw new RuntimeException("隊列已滿!"); } elem[rear] = value; rear = (rear + 1) % elem.length; flag = false; return true; } // 從循環(huán)隊列中刪除一個元素。如果成功刪除則返回真。 public boolean deQueue() { if (isEmpty()) { return false; // throw new RuntimeException("隊列為空!"); } front = (front + 1) % elem.length; flag = true; return true; } // 從隊首獲取元素。如果隊列為空,返回 -1 。 public int Front() { if (isEmpty()) { return -1; // throw new RuntimeException("隊列為空!"); } return elem[front]; } // 獲取隊尾元素。如果隊列為空,返回 -1 。 public int Rear() { if (isEmpty()) { return -1; // throw new RuntimeException("隊列為空!"); } // 如果是0下標,拿最后一個元素 if (rear == 0) { return elem[elem.length-1]; }else { return elem[rear - 1]; } } // 檢查循環(huán)隊列是否為空。 public boolean isEmpty() { if (rear == front && flag){ return true; } return false; } // 檢查循環(huán)隊列是否已滿。 public boolean isFull() { if (rear == front && !flag){ return true; } return false; } }
到此這篇關于Java 棧與隊列超詳細分析講解的文章就介紹到這了,更多相關Java 棧與隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- java 數(shù)據(jù)結(jié)構(gòu)之棧與隊列
- java 數(shù)據(jù)結(jié)構(gòu)中棧和隊列的實例詳解
- Java深入了解數(shù)據(jù)結(jié)構(gòu)之棧與隊列的詳解
- Java 棧和隊列的相互轉(zhuǎn)換詳解
- Java棧和基礎隊列的實現(xiàn)詳解
- 一起來學習Java的棧和隊列
- Java?棧與隊列實戰(zhàn)真題訓練
- Java使用跳轉(zhuǎn)結(jié)構(gòu)實現(xiàn)隊列和棧流程詳解
- Java線性結(jié)構(gòu)中棧、隊列和串的基本概念和特點詳解
- Java常見的數(shù)據(jù)結(jié)構(gòu)之棧和隊列詳解
- Java 棧和隊列的交互實現(xiàn)
相關文章
在windows環(huán)境下安裝jdk8、jdk9、jdk11、jdk12并自由切換
這篇文章主要介紹了在windows環(huán)境下安裝jdk8、jdk9、jdk11、jdk12并自由切換,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05SpringBoot實現(xiàn)過濾器Filter的三種方式
過濾器Filter由Servlet提供,基于函數(shù)回調(diào)實現(xiàn)鏈式對網(wǎng)絡請求與響應的攔截與修改,本文講給大家詳細介紹SpringBoot實現(xiàn)過濾器Filter的三種方式,需要的朋友可以參考下2023-08-08SpringBoot JdbcTemplate批量操作的示例代碼
本篇文章主要介紹了SpringBoot JdbcTemplate批量操作的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04MAC配置java+jmeter環(huán)境變量過程解析
這篇文章主要介紹了MAC配置java+jmeter環(huán)境變量過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09