數據結構*棧

什么是棧

這里的棧與我們之前常說的棧是不同的。之前我們說的棧是內存棧,它是JVM內存的一部分,用于存儲局部變量、方法調用信息等。每個線程都有自己獨立的棧空間,當線程啟動時,棧就會被創建;線程結束,棧也會被銷毀。
而數據結構中的棧是一種抽象數據類型,描述的是一種存儲數據的一種方法,遵循“先進后出”的原則,是一種線性的數據結構。
在這里插入圖片描述
像上圖所示就是一個棧,只能對于頂部完成操作,放元素放在最上面,當要拿棧中的元素也只能從最上面的元素開始獲取。

官方棧

Stack類中的方法

方法功能
Stack()構造方法
E push(E e)將e入棧
E pop()將棧頂元素出棧并返回
E peek()獲取棧頂元素
int size獲取棧中的有效元素個數
boolean empty()棧中是否為空
int search(Object o)

代碼展示:

public static void test1() {Stack<Integer> stack = new Stack<>();stack.push(10);stack.push(20);stack.push(30);stack.push(40);stack.pop();System.out.println(stack);//[10, 20, 30]System.out.println(stack.size());//3System.out.println(stack.peek());//30System.out.println(stack.empty());//falseSystem.out.println(stack.search(10));//3
}

代碼解釋:

1、對于search方法的返回:如果對象存在于棧中,會返回該對象到棧頂的距離(棧頂元素的距離為 1);若對象不在棧中,則返回 -1。
2、由于Stack繼承了Vector等其他類,也可以調用Vecto等其他類中的方法。

用數組自己實現一個棧

代碼展示:

import java.util.Arrays;
public class MyStack<E> {private Object[] elem;private int useSize;public static final int DEFAULT_CAPACITY = 10;public MyStack() {elem = new Object[DEFAULT_CAPACITY];}/*** 完成入棧操作*/public void push(E data) {if(isFull()) {elem = Arrays.copyOf(elem,elem.length*2);}elem[useSize] = data;useSize++;}/*** 完成出棧操作,將棧頂的元素出棧并返回*/public E pop() {if(isEmpty()) {return null;}E ret = (E)elem[useSize - 1];useSize--;return ret;}/*** 返回棧頂的元素*/public E peek() {if(elem == null) {return null;}return (E)elem[useSize - 1];}/*** 棧中的元素個數* @return*/public int size() {return useSize;}private boolean isFull() {return elem.length == useSize;}public boolean isEmpty() {return useSize == 0;}public void display() {for (int i = 0; i < useSize; i++) {System.out.print(elem[i] + " ");}System.out.println();}
}

代碼解釋:

1、定義的 MyStack 類屬于泛型類,也就是 MyStack<E>,E 代表元素的類型,不過在編譯時具體類型是未知的。Java 并不允許創建泛型數組,也就是不能直接寫 E[] elem = new E[DEFAULT_CAPACITY]; 。這是由于 Java 的泛型是通過類型擦除來實現的,在運行時泛型類型信息會被擦除,因此無法創建泛型數組。此時,借助 Object 數組,能夠存儲任意類型的對象。
2、Stack類底層使用數組實現的,當然我們也可以用鏈表實現Stack類。
3、 我們也可以使用鏈表的形式實現棧,在LinkedList類中也有push、pop、peek方法等方法。

棧的使用

1、用棧實現逆序打印鏈表

對于之前實現是通過遞歸的方法

public void printList(ListNode head) {ListNode cur = head;if(head != null) {printList(cur.next);System.out.print(cur.value + " ");}
}

通過遞歸回代的機制實現鏈表的逆序打印。
這也可以看成先進后出的。正序是從頭開始打印,先將元素放在棧中,在開始取出元素,取出的元素對于鏈表來說就是逆序輸出。

public void print(ListNode head) {ListNode cur = head;if(head == null) {return;}Stack<ListNode> stack = new Stack<>();//從頭節點開始依次存入棧中while (cur != null) {stack.push(cur);cur = cur.next;}//開始取出元素,此時取出的是鏈表中最后的節點,因為它是最后放入棧中的while (!stack.empty()) {System.out.print(stack.pop().value + " ");}System.out.println();
}

2、逆波蘭表達式

逆波蘭表達式也叫后綴表達式。我們平常算數用的是中綴表達式(例如:1 + 2 = 3)。關于后綴表達式怎么從中綴表達式得來的,可以自行百度。下面是豆包給出來的運算方法。
在這里插入圖片描述

代碼展示:
public int evalRPN(String[] tokens) {Stack<Integer> stack = new Stack<>();for(String string : tokens) {if(!isOperations(string)) {//是數字將其存入棧中stack.push(Integer.parseInt(string));}else {//是操作符,取出兩個數字進行計算,將運算的數字在存入棧中int right = stack.pop();int left = stack.pop();switch (string){case "+" :stack.push(left + right);break;case "-" :stack.push(left - right);break;case "*" :stack.push(left * right);break;case "/" :stack.push(left / right);break;}}}//返回棧中最后一個元素了return stack.pop();
}
private boolean isOperations(String string) {return string.equals("+") || string.equals("-") || string.equals("*") || string.equals("/");
}

3、棧的壓入與彈出序列

代碼展示:
public boolean IsPopOrder (int[] pushV, int[] popV) {Stack<Integer> stack = new Stack<>();int j = 0;for (int i = 0; i < pushV.length; i++) {stack.push(pushV[i]);while (!stack.empty() && j < popV.length && stack.peek() == popV[j]){stack.pop();j++;}}return stack.empty();
}
代碼解釋:

for循環是將pushV數組中的元素依次放在棧中。while循環是按照popV數組取出來的,當棧頂上的元素等于popV中的第一個元素,就從棧中取出,popV往后走。為什么判斷條件要有!stack.empty()?是因為防止stack.peek()為空指針異常。

4、最小棧

代碼展示:
class MinStack {Stack<Integer> stack;Stack<Integer> minStack;public MinStack() {stack = new Stack<>();minStack = new Stack<>();}public void push(int val) {stack.push(val);if(minStack.empty()) {minStack.push(val);}else {if(val <= minStack.peek()) {minStack.push(val);}}}public void pop() {int popVal = stack.pop();if(popVal == minStack.peek()) {minStack.pop();}}public int top() {return stack.peek();}public int getMin() {return minStack.peek();}
}
代碼解釋:

1、在push()方法中將小的之push到minStack棧中。此時需要注意的是,當有兩個緊挨一樣的最小值,它們都需要push到minStack棧中,因為當stack棧中pop了這個值,但最小值還是它。
2、在pop方法中if語句的判斷條件需要注意。由于棧中存儲的是Integer類對象,比較時不能直接用等號(stack.pop() == minStack.peek()像這樣是錯的)。可以定義int類型的臨時變量,在比較的時候Integer類型的會自動拆箱。(在push方法中if語句比較也是一樣的)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903928.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903928.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903928.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IntelliJ IDEA 保姆級使用教程

文章目錄 一、創建項目二、創建模塊三、創建包四、創建類五、編寫代碼六、運行代碼注意 七、IDEA 常見設置1、主題2、字體3、背景色 八、IDEA 常用快捷鍵九、IDEA 常見操作9.1、類操作9.1.1、刪除類文件9.1.2、修改類名稱注意 9.2、模塊操作9.2.1、修改模塊名快速查看 9.2.2、導…

HTTP 快速解析

一、HTTP請求結構 HTTP請求和響應報文由以下部分組成&#xff08;以請求報文為例&#xff09;&#xff1a; 請求報文結構&#xff1a; 請求行&#xff1a;包含HTTP方法&#xff08;如GET/POST&#xff09;、請求URL和協議版本&#xff08;如HTTP/1.1&#xff0c;HTTP/2.0&…

【AI學習】李宏毅新課《DeepSeek-R1 這類大語言模型是如何進行「深度思考」(Reasoning)的?》的部分紀要

針對推理模型&#xff0c;主要講了四種方法&#xff0c;兩種不需要訓練模型&#xff0c;兩種需要。 對于reason和inference&#xff0c;這兩個詞有不同的含義&#xff01; 推理時計算不是新鮮事&#xff0c;AlphaGo就是如此。 這張圖片說明了將訓練和推理時計算綜合考慮的關系&…

Kotlin Flow流

一 Kotlin Flow 中的 stateIn 和 shareIn 一、簡單比喻理解 想象一個水龍頭&#xff08;數據源&#xff09;和幾個水杯&#xff08;數據接收者&#xff09;&#xff1a; 普通 Flow&#xff08;冷流&#xff09;&#xff1a;每個水杯來接水時&#xff0c;都要重新打開水龍頭從…

【嵌入式Linux】基于ARM-Linux的zero2平臺的智慧樓宇管理系統項目

目錄 1. 需求及項目準備&#xff08;此項目對于虛擬機和香橙派的配置基于上一個垃圾分類項目&#xff0c;如初次開發&#xff0c;兩個平臺的環境變量&#xff0c;阿里云接入&#xff0c;攝像頭配置可參考垃圾分類項目&#xff09;1.1 系統框圖1.2 硬件接線1.3 語音模塊配置1.4 …

Linux運維中常用的磁盤監控方式

在Linux運維中&#xff0c;磁盤監控是一項關鍵任務&#xff0c;因為它能幫助我們預防磁盤空間不足或性能問題導致的服務中斷或數據丟失。讓我們來看看有哪些常用的磁盤監控方法吧&#xff01; 1. 查看磁盤使用情況&#xff08;df命令&#xff09; df命令用于顯示文件系統的…

OpenCV第6課 圖像處理之幾何變換(縮放)

1.簡述 圖像幾何變換又稱為圖像空間變換,它將一幅圖像中的坐標位置映射到另一幅圖像中的新坐標位置。幾何變換并不改變圖像的像素值,只是在圖像平面上進行像素的重新安排。 根據OpenCV函數的不同,本節課將映射關系劃分為縮放、翻轉、仿射變換、透視等。 2.縮放 2.1 函數…

(35)VTK C++開發示例 ---將圖片映射到平面2

文章目錄 1. 概述2. CMake鏈接VTK3. main.cpp文件4. 演示效果 更多精彩內容&#x1f449;內容導航 &#x1f448;&#x1f449;VTK開發 &#x1f448; 1. 概述 與上一個示例不同的是&#xff0c;使用vtkImageReader2Factory根據文件擴展名或內容自動創建對應的圖像文件讀取器&a…

【模型量化】量化基礎

目錄 一、認識量化 二、量化基礎原理 2.1 對稱量化和非對稱量化 2.1.1 對稱量化 2.1.2 非對稱量化 2.1.3 量化后的矩陣乘 2.2 神經網絡量化 2.2.1 動態量化 2.2.2 靜態量化 2.3 量化感知訓練 一、認識量化 量化的主要目的是節約顯存、提高計算效率以及加快通信 dee…

【零基礎入門】一篇掌握Python中的字典(創建、訪問、修改、字典方法)【詳細版】

?? 個人主頁:十二月的貓-CSDN博客 ?? 系列專欄: ??《PyTorch科研加速指南:即插即用式模塊開發》-CSDN博客 ???? 十二月的寒冬阻擋不了春天的腳步,十二點的黑夜遮蔽不住黎明的曙光 目錄 1. 前言 2. 字典 2.1 字典的創建 2.1.1 大括號+直接賦值 2.1.2 大括號…

PHP-session

PHP中&#xff0c;session&#xff08;會話&#xff09;是一種在服務器上存儲用戶數據的方法&#xff0c;這些數據可以在多個頁面請求或訪問之間保持。Session提供了一種方式來跟蹤用戶狀態&#xff0c;比如登錄信息、購物車內容等。當用戶首次訪問網站時&#xff0c;服務器會創…

第 5 篇:紅黑樹:工程實踐中的平衡大師

上一篇我們探討了為何有序表需要“平衡”機制來保證 O(log N) 的穩定性能。現在&#xff0c;我們要認識一位在實際工程中應用最廣泛、久經考驗的“平衡大師”——紅黑樹 (Red-Black Tree)。 如果你用過 Java 的 TreeMap? 或 TreeSet?&#xff0c;或者 C STL 中的 map? 或 s…

第十六屆藍橋杯 2025 C/C++組 客流量上限

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 打表找規律&#xff1a; 核心思路&#xff1a; 思路詳解&#xff1a; 得到答案的方式&#xff1a; 按計算器&#xff1a; 暴力求解代碼&#xff1a; 快速冪代碼&#xff1a; 位運…

一天學完JDBC!!(萬字總結)

文章目錄 JDBC是什么 1、環境搭建 && 入門案例2、核心API理解①、注冊驅動(Driver類)②、Connection③、statement(sql注入)④、PreparedStatement⑤、ResultSet 3、jdbc擴展(ORM、批量操作)①、實體類和ORM②、批量操作 4. 連接池①、常用連接池②、Durid連接池③、Hi…

從原理到實戰講解回歸算法!!!

哈嘍&#xff0c;大家好&#xff0c;我是我不是小upper, 今天系統梳理了線性回歸的核心知識&#xff0c;從模型的基本原理、參數估計方法&#xff0c;到模型評估指標與實際應用場景&#xff0c;幫助大家深入理解這一經典的機器學習算法&#xff0c;助力數據分析與預測工作。 …

【dify—10】工作流實戰——文生圖工具

目錄 一、創建工作流 應用 二、安裝硅基流動 三、配置硅基流動 四、API測試 &#xff08;1&#xff09;進入API文檔 &#xff08;2&#xff09;復制curl代碼 &#xff08;3&#xff09;Postman測試API 五、 建立文生圖工作流 &#xff08;1&#xff09;建立http請求 &…

Rust將結構導出到json如何處理小數點問題

簡述 標準的 serde_json 序列化器不支持直接對浮點數進行格式化限制。如果將浮點數轉換成字符串&#xff0c;又太low逼。這里重點推薦rust_decimal。 #[derive(Serialize)] pub struct StockTickRow {datetime: NaiveDateTime,code: String,name: String,#[serde(serialize_w…

openEuler 22.03 安裝 Redis 6.2.9,支持離線安裝

目錄 一、環境檢查1.1 必要環境檢查1.2 在線安裝&#xff08;有網絡&#xff09;1.3 離線安裝&#xff08;無網絡&#xff09; 二、下載Redis2.1 在線下載2.2 離線下載 三、安裝Redis四、配置Redis服務五、開機自啟服務六、開放防火墻端口七、常用命令 一、環境檢查 1.1 必要環…

MySQL基本查詢(二)

文章目錄 UpdateDelete插入查詢結果&#xff08;select insert&#xff09;聚合函數分組聚合統計 Update 1. 語法&#xff1a; set后面加列屬性或者表達式 UPDATE table_name SET column expr [, column expr …][WHERE …] [ORDER BY …] [LIMIT …] 案例 將孫悟空同學的…

Android Framework學習二:Activity創建及View繪制流程

文章目錄 Window繪制流程Window Manager Service&#xff08;WMS&#xff09;SurfaceSurfaceFlinger 安卓View層次結構ActivityPhoneWindowActivity與PhoneWindow兩者之間的關系ViewRootImplDecorViewDecorView 的作用DecorView 的結構總結 Activity創建流程View invalidate調用…