【Java】棧和隊列

文章目錄

  • 1.棧
    • 1.1 棧的定義
    • 1.2 棧的使用
    • 1.3 棧的模擬實現
  • 2.隊列
    • 2.1 隊列的定義
    • 2.2 隊列的使用
    • 2.3 隊列的模擬實現
  • 3.循環隊列
    • 3.1 循環隊列的概念
    • 3.2 循環隊列判斷空和滿
  • 4.雙端隊列Deque


1.棧

1.1 棧的定義

棧是一種特殊的線性表,其只允許在固定的一段進行數據的插入或者刪除。一般,插入或刪除元素的一端叫棧頂,棧頂的另一端一般叫做棧底。棧中的元素均遵循后進先出(LIFO)的原則。

image-20250805103123153

1.2 棧的使用

棧的常用方法為:

方法功能
Stack()構造空棧
E push(E e)將元素入棧,并返回該元素
E pop()棧頂元素出棧并返回該元素
E peek()獲取棧頂元素
int size()獲取棧中的元素個數
boolean empty()判斷棧是否為空
public static void main(String[] args) {Stack<Integer> s=new Stack<>();s.push(1);s.push(2);s.push(3);System.out.println("棧的大小為:"+s.size());System.out.println("棧頂元素為:"+s.peek());System.out.println("出棧元素為:"+s.pop());System.out.println("出棧后的棧頂元素為:"+s.peek());s.pop();s.pop();if(s.empty()) {System.out.println("當前棧為空");}
}

1.3 棧的模擬實現

image-20250805103721994

圖中可以看出,Stack繼承了Vector類,Vector和ArrayList類似,都是會動態增長的順序表。

public class MyStack<E> {  private Object[] elem;private int elemSize;//構造方法public MyStack() {}public MyStack(int capacity) {}//元素入棧并返回public E push(E e) {}//元素出棧并返回public E pop() {}//獲取棧頂元素public E peek() {}//獲得棧中元素個數public int size() {}//判斷是否為空棧public boolean empty() {}
}

1.入棧:

public E push(E e) {if(elem.length==elemSize) {this.elem=Arrays.copyOf(elem,2*elem.length);}elem[elemSize++]=e;return e;
}

2.出棧:

public E pop() {if(size()==0) {throw new RuntimeException("棧中不存在元素,無法刪除");}E obj=peek();elemSize--;return obj;
}

3.獲取棧頂元素

public E peek() {int len=size();if(len==0) {throw new RuntimeException("棧中不存在元素");}return (E)elem[len-1];
}

4.判空與獲取大小

//獲得棧中元素個數
public int size() {return elemSize;
}//判斷是否為空棧
public boolean empty() {return elemSize==0;
}

5.測試結果:

image-20250805123124671

2.隊列

2.1 隊列的定義

隊列是一種特殊的線性表。其是只允許在一端進行插入,在另一端進行刪除的結構

插入端即隊尾(Tail/Rear),刪除端為隊頭(Head/Front)。對元素的操作遵循先入先出(FIFO)的原則。

image-20250805130401181

2.2 隊列的使用

image-20250805130340988

可以看到,LinkedList類實現了Queue接口,因此需要用LinkedList類來實例化對象;

方法功能
boolean offer(E e)將元素入隊
E poll()隊頭元素出隊并返回該元素
E peek()獲取隊頭元素
int size()獲取隊列中的元素個數
boolean isEmpty()判斷隊列是否為空
public static void main(String[] args) {Queue<Integer> q=new LinkedList<>();q.offer(1);q.offer(2);q.offer(3);  //1,2,3System.out.println(q.poll()); System.out.println(q.peek());System.out.println("隊列為空嗎?"+q.isEmpty());
}

2.3 隊列的模擬實現

隊列的實現既可以用數組也可以用列表實現;雖然在Java中使用鏈表來實現隊列,但其常數時間的并不是很好,因此,如果在刷題,尤其是競賽等場景(數據量確定),用數組去模擬隊列會是更好的寫法;

這里使用雙端鏈表來模擬實現:

public class MyQueue<E> {class ListNode{private E val;private ListNode prev;private ListNode next;public ListNode(E val) {this.val=val;}}private ListNode head;  //頭指針private ListNode tail;  //尾指針private int usedSize;   //當前隊列大小//元素從隊尾入隊列public boolean offer(E e) {}//隊頭元素出隊列public E poll() {}//獲取隊頭元素public E peek() {}//獲取隊列元素個數public int size() {return usedSize;}//判斷隊列是否為空public boolean isEmpty() {return usedSize==0;}
}

1.入隊列:

public boolean offer(E e) {ListNode node=new ListNode(e);//空隊列if(usedSize==0) {head=tail=node;}else {tail.next=node;node.prev=tail;tail=tail.next;}this.usedSize++;return true;
}

2.出隊列:

public E poll() {if(usedSize==0) {throw new RuntimeException("當前隊列為空");}E obj=head.val;if(head==tail) {head=tail=null;}else {head=head.next;head.prev=null;}usedSize--;return obj;
}

3.獲取隊頭元素

public E peek() {if(usedSize==0) {throw new RuntimeException("隊列為空");}return head.val;
}

4.測試結果:

image-20250806110838896

3.循環隊列

3.1 循環隊列的概念

循環隊列簡單來說就是一個將隊列的首尾相連接的特殊隊列;循環隊列通常采用數組實現

image-20250806112059232

3.2 循環隊列判斷空和滿

1.使用size記錄循環隊列大小

if(front==rear&&size==0)System.out.println("循環隊列為空")
if(front==rear&&size!=0)System.out.println("循環隊列為滿")

2.使用標記

  1. 初始狀態:隊列為空,front==rear&&isFull=false
  2. 入隊前,檢查front與rear是否重合,重合則isFull=true,即隊列滿,否則rear移動
  3. 出隊時,front移動,isFull=false

3.保留一個位置

image-20250806125717458

  • 隊列為空:front==rear
  • 隊列為滿:(rear+1)%capacity
  • rear的循環移動:rear=(rear+1)%capacity

4.雙端隊列Deque

image-20250807100634548

雙端隊列是可以在兩端均進行插入和刪除的隊列;即隊頭隊尾均可以進行出隊入隊,

因此Deque既可以當作隊列也可以當作棧使用

Deque是接口,因此使用時必須用LinkedList創建對象

Deque常見的實現類為:

Deque<Integer> stack=new ArrayDeque<>();
Deque<Integer> queue=new LinkedList<>();

-----------------------------------------------------------------------------完-----------------------------------------------------------------------------

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

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

相關文章

【性能測試】---測試工具篇(jmeter)

目錄 1、安裝并啟動jemeter 2、重點組件 2.1、線程組&#xff1a; 2.2、HTTP取樣器?編輯 2.3、查看結果樹 2.4、HTTP請求默認值 2.5、HTTP信息頭管理器 2.6、JSON提取器 2.7、JSON斷言 2.8、同步定時器 2.9、CSV數據文件設置 2.10、HTTP Cookie管理器 3、測試報告…

機器學習(12):拉索回歸Lasso

- 拉索回歸可以將一些權重壓縮到零&#xff0c;從而實現特征選擇。這意味著模型最終可能只包含一部分特征。 - 適用于特征數量遠大于樣本數量的情況&#xff0c;或者當特征間存在相關性時&#xff0c;可以從中選擇最相關的特征。 - 拉索回歸產生的模型可能更簡單&#xff0c;因…

Redis持久化存儲

Redis持久化存儲詳解 一、核心持久化機制 Redis提供兩種主要持久化方式&#xff1a;RDB&#xff08;快照&#xff09; 和 AOF&#xff08;追加文件&#xff09;&#xff0c;以及兩者的混合模式。 RDB&#xff08;Redis Database&#xff09;快照持久化 工作原理 RDB通過創建數據…

python學智能算法(三十四)|SVM-KKT條件回顧

【1】引言 前序學習進程中&#xff0c;對軟邊界拉格朗日方程進行了初步構建。 其中約定了兩個拉格朗日乘子要非負&#xff0c;其本質是要滿足KKT條件。 今天就乘此次機會&#xff0c;在回顧一下KKT條件。 【2】定義 當問題無約束的時候&#xff0c;只要讓函數梯度為零&#…

【網絡基礎】計算機網絡發展背景及傳輸數據過程介紹

本文旨在幫助初學者建立起計算機網絡的基礎認知&#xff0c;從網絡的發展背景到網絡協議的分層模型&#xff0c;再到IP與MAC地址的基本概念&#xff0c;全面覆蓋第一階段學習重點。 &#x1f4cc; 本節重點 了解計算機網絡的發展背景&#xff0c;掌握局域網&#xff08;LAN&am…

阿里云-通義靈碼:解鎖云原生智能開發新能力,讓云開發更“靈”~

免責聲明&#xff1a;此篇文章所有內容皆是本人實驗&#xff0c;并非廣告推廣&#xff0c;并非抄襲&#xff0c;如有侵權&#xff0c;請聯系筆者。 每日一句 信念其實就是相信未來&#xff0c; 相信內在&#xff0c; 以及坦然美好的心境。 目錄 每日一句 一. 引言 二.通義…

lesson33:Python協程詳解:從原理到實戰的異步編程指南

目錄 一、協程核心概念&#xff1a;輕量級并發的本質 1.1 什么是協程&#xff1f; 1.2 協程與線程/進程的對比 二、協程工作原理&#xff1a;事件循環與協作式調度 2.1 事件循環&#xff08;Event Loop&#xff09;&#xff1a;協程的"調度中心" 2.2 協作式調度…

深入理解C++模板進階:非類型參數、特化與分離編譯

前言C模板是泛型編程的核心&#xff0c;它允許我們編寫與類型無關的代碼。在掌握了模板的基礎知識后&#xff0c;我們需要進一步了解模板的高級特性&#xff0c;以便更靈活地使用它們。本文將深入探討三個重要的模板進階主題&#xff1a;非類型模板參數、模板特化以及模板的分離…

使用winsw把SpringBoot項目注冊成window服務

目錄 一、使用winsw注冊 1.1、項目打jar包 1.2、下載winsw 1.3、把 WinSW.NET4.exe 重新命名 1.4、編寫m配置文件用于配置注冊信息 1.5、創建文件夾存放你的文件 1.6、安裝服務 1.7、啟動服務 1.8、卸載服務 1.8、停止服務 一、使用winsw注冊 1.1、項目打jar包 例如項目jar包名…

進階向:Python開發簡易QQ聊天機器人

數字化時代的聊天機器人應用在當今數字化時代&#xff0c;聊天機器人已經成為日常生活和商業活動中不可或缺的一部分。根據市場研究數據顯示&#xff0c;全球聊天機器人市場規模預計將在2026年達到102億美元&#xff0c;年復合增長率達到34.75%。這些智能助手正廣泛應用于以下場…

基于開源鏈動2+1模式AI智能名片S2B2C商城小程序的用戶留存策略研究

摘要&#xff1a;在數字化商業競爭白熱化的當下&#xff0c;用戶留存成為企業可持續發展的核心命題。本文聚焦開源鏈動21模式AI智能名片S2B2C商城小程序這一創新技術組合&#xff0c;通過分析其技術架構、模式創新與生態閉環的協同效應&#xff0c;揭示其在降低用戶決策成本、提…

單詞的劃分(動態規劃)

題目描述有一個很長的由小寫字母組成字符串。為了便于對這個字符串進行分析&#xff0c;需要將它劃分成若干個部分&#xff0c;每個部分稱為一個單詞。出于減少分析量的目的&#xff0c;我們希望劃分出的單詞數越少越好。你就是來完成這一劃分工作的。輸入第一行&#xff0c;一…

C語言學習筆記——文件

目錄1 文件的概念2 程序文件和數據文件3 二進制文件和文本文件4 流4.1 流的概念4.2 標準流5 文件信息區和文件指針6 處理文件的庫函數6.1 fopen6.2 fclose6.3 fgetc6.4 fputc6.5 fgets6.6 fputs6.7 fscanf6.8 fprintf6.9 fread6.10 fwrite6.11 fseek6.12 ftell6.13 rewind6.14 …

C++語法與面向對象特性(2)

一.inline函數1.inline的基本特性被inline修飾的函數被稱為內聯函數。inline函數設計的初衷是為了優化宏的功能&#xff0c;編譯器會在編譯階段對inline函數進行展開。然而需要注意的是&#xff0c;inline對于編譯器而言是一種建議&#xff0c;它通常會展開一些簡短的&#xff…

Linux中grep命令

Linux 中的 grep 用法詳解grep 是 Linux 中強大的文本搜索工具&#xff0c;用于在文件或輸入流中查找匹配指定模式的行。其基本語法為&#xff1a;grep [選項] "模式" [文件]核心功能基礎搜索在文件中查找包含特定字符串的行&#xff1a;grep "error" log.…

【遙感圖像入門】遙感中的“景”是什么意思?

在遙感成像中,“3景城市影像”和“5景城市影像”中的“景”是遙感數據的基本單位,通常指一次成像過程中獲取的獨立遙感影像塊。這一概念的具體含義需結合技術背景和應用場景理解: 一、“景”的技術定義 單次成像的獨立覆蓋區域 遙感平臺(如衛星、飛機)在特定時間和位置對…

Pytorch-07 如何快速把已經有的視覺模型權重扒拉過來為己所用

下載&#xff0c;保存&#xff0c;加載&#xff0c;使用模型權重 在這一節里面我們會過一遍對模型權重的常用操作&#xff0c;比如&#xff1a; 如何下載常用模型的預訓練權重如何下載常用模型的無訓練權重&#xff08;只下載網絡結構&#xff09;如何加載模型權重如何保存權…

C語言零基礎第9講:指針基礎

目錄 1.內存和地址 2.指針變量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指針變量 2.3 解引用操作符&#xff08;*&#xff09; 2.4 指針變量的大小 3.指針變量類型的意義 3.1 指針的解引用 3.2 指針 - 整數 3.3 void*指針 4.指針運算 4.1 指針…

013 HTTP篇

3.1 HTTP常見面試題 1、HTTP基本概念&#xff1a; 超文本傳輸協議&#xff1a;在計算機世界里專門在「兩點」之間「傳輸」文字、圖片、音頻、視頻等「超文本」數據的「約定和規范」HTTP常見的狀態碼 [[Pasted image 20250705140705.png]]HTTP常見字段 Host 字段&#xff1a;客戶…

每日面試題20:spring和spring boot的區別

我曾經寫過一道面試題&#xff0c;題目是為什么springboot項目可以直接打包給別人運行&#xff1f;其實這涉及到的就是springboot的特點。今天來簡單了解一下springboot和spring的區別&#xff0c; Spring 與 Spring Boot&#xff1a;從“全能框架”到“開箱即用”的進化之路 …