目錄
1. 堆疊的概念
2. 堆疊的使用
3. 堆疊的OJ題
4. 堆疊的模擬實作
5. 堆疊,虛擬機堆疊,堆疊幀的區別
1. 堆疊的概念
堆疊是一種特殊的線性表,它只能在固定的一端進行插入和洗掉操作,進行資料插入和洗掉的一端為堆疊頂,另一端為堆疊底,堆疊中的元素遵循后進先出(LIFO)(Last In First Out)的原則,
壓堆疊:堆疊的插入資料操作叫做進堆疊,壓堆疊,入堆疊,入資料在堆疊頂
出堆疊:堆疊的洗掉操作叫做出堆疊,出資料在堆疊頂

2. 堆疊的使用
| 方法 | 功能說明 |
| Stack() | 構造一個空堆疊 |
| E push(E e) | 將e入堆疊并回傳e |
| E pop() | 將堆疊頂元素出堆疊并回傳 |
| E peek() | 獲取堆疊頂元素 |
| int size() | 獲取堆疊中有效元素的個數 |
| boolean empty() | 檢測堆疊是否為空 |
將上述方法進行代碼展示:
public class TestStack {
public static void main(String[] args) {
Stack<Integer> s = new Stack<>();
s.push(1);
s.push(2);
s.push(3);
s.push(4);
System.out.println(s.size());
s.pop();
System.out.println(s.peek());
if(s.empty()){
System.out.println("堆疊空");
}else{
System.out.println("堆疊不空,元素個數為:"+s.size());
}
}
//結果:
4
3
堆疊不空,元素個數為:3
使用堆疊將遞回轉化為回圈:
// 遞回方式
void printList(Node node){
if(null != node){
printList(node.next);
System.out.print(node.val + " ");
}
}
// 回圈方式
void printList(Node node){
if(null == node){
return;
}
Stack<Node> s = new Stack<>();
// 將鏈表中的結點保存在堆疊中
Node cur = node;
while(null != cur){
s.push(cur);
cur = cur.next;
}
// 將堆疊中的元素出堆疊
while(!s.empty()){
System.out.print(s.pop().val + " ");
}
}
3. 堆疊的OJ題
1. 括號匹配(LeetCode20)有效的括號
可以進入上面鏈接查看題目
方法:
1. 依次拿到字串的元素,如果該元素是左括號,則入堆疊
2. 如果不是左括號,先判斷堆疊是否為空,如果為空則回傳false,如果不為空則進行后續操作
3. 拿到堆疊頂的元素與前面所拿到字串的元素作比較,如果括號匹配,則堆疊頂元素出堆疊,結束當前回圈,繼續進行后續比較,如果括號不匹配,則回傳false
4. 當字串的元素比較完后,判斷堆疊是否有剩余,如果有剩余,則回傳false,無剩余則回傳true
參考代碼:
class Solution {
public boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for(int i=0;i<s.length();i++){
char c = s.charAt(i);
if(c=='('||c=='{'||c=='['){
stack.push(c);
}else{
if(stack.empty()){
return false;
}
char top = stack.pop();
if(top=='{'&&c=='}'||top=='['&&c==']'||top=='('&&c==')'){
continue;
}else{
return false;
}
}
}
if(!stack.empty()){
return false;
}
return true;
}
}
2.逆波蘭運算式求值(LeetCode150)逆波蘭運算式求值
可以進入上面鏈接查看題目
方法:
1. 依次將字串入堆疊,如果字串不是算數符號,則入堆疊
2. 當字串是算數符號的時候,取堆疊頂的兩個元素進行算數運算
3. 將運算的結果繼續入堆疊
4. 依次進行上述回圈
5. 最后回傳堆疊頂元素的值,即所求逆波蘭運算式的值
參考代碼:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> s = new Stack<>();
for(String e : tokens){
if(!(e.equals("+")||e.equals("-")||e.equals("*")||e.equals("/"))){
s.push(Integer.parseInt(e));//將字符e轉為整型
}else{
int right = s.pop();
int left = s.pop();
switch(e) {
case "+":
s.push(left+right);
break;
case "-":
s.push(left-right);
break;
case "*":
s.push(left*right);
break;
case "/":
s.push(left/right);
break;
}
}
}
return s.peek();
}
}
3. 出堆疊入堆疊次序匹配(JZ31)堆疊的壓入、彈出序列
方法:
1. 當入堆疊序列的元素小于出堆疊序列的第一個元素,將入堆疊序列的元素依次入堆疊
2. 每入堆疊一個元素,入堆疊序列的下標加1
3. 當入堆疊序列的元素與出堆疊序列的元素相等時,進行出堆疊,并且出堆疊序列下標加1
4. 當出堆疊序列的元素遍歷完后,回傳true
參考代碼:
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> s = new Stack<>();
int inIndex = 0;
int outIndex = 0;
while(outIndex<popped.length){
while(s.empty()||s.peek()!=popped[outIndex]){
if(inIndex<pushed.length){
s.push(pushed[inIndex]);
inIndex++;
}
else{
return false;
}
}
s.pop();
outIndex++;
}
return true;
}
}
4. 堆疊的模擬實作
public class MyStack<E> {
E[] array;
int size;
public MyStack(){
array = (E[])new Object[3];
}
public E push(E e){
ensureCapacity();
array[size++] = e;
return e;
}
public E pop(){
E e = peek();
size--;
return e;
}
public E peek(){
if(empty()){
throw new RuntimeException("堆疊為空,無法獲取堆疊頂元素");
}
return array[size-1];
}
public int size(){
return size;
}
public boolean empty(){
return 0 == size;
}
private void ensureCapacity(){
if(size == array.length){
array = Arrays.copyOf(array, size*2);
}
}
}
5. 堆疊,虛擬機堆疊,堆疊幀的區別
堆疊:一種后進先出的資料結構,繼承自Vector
虛擬機堆疊:具有特殊作用的一塊記憶體空間,堆疊區:是執行緒私有的,存放的是函式呼叫相關資訊,主要是堆疊幀,它是按照資料結構中堆疊的特性來實作的
堆疊幀:一種結構,與函式呼叫相關,內部:區域變數表,運算元堆疊,每個方法運行時JVM會創建一個堆疊幀,然后將堆疊幀壓到虛擬機堆疊中,呼叫結束時,該方法對應的堆疊幀會從虛擬機堆疊中出堆疊,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/356117.html
標籤:其他
