StackQueue+泛型簡單理解

  • 🍁?個人主頁:愛編程的Tom
  • 💫 本篇博文收錄專欄:Java專欄
  • 👉?目前其它專欄:c系列小游戲?????c語言系列--萬物的開始_??? ? ? ? ? ? ?
  • 🎉 歡迎 👍點贊?評論?收藏💖三連支持一下博主🤞
  • 🧨現在的沉淀就是對未來的鋪墊🎨?

目錄

前言

棧(Stack)

棧的定義

棧的使用?

棧的模擬實現?

棧的應用場景

改變元素的序列 ?

將遞歸轉化為循環?

隊列(Queue)?

隊列的定義?

隊列的使用?

隊列模擬實現?

循環隊列?

雙端隊列 (Deque)?

泛型



?

前言

本篇文章將帶你深入了解棧和隊列的底層知識和基礎架構,學會使用對數據的組織和運用!

棧(Stack)

棧的定義

棧:一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作

進行數據插入和刪除操作的一端稱為棧頂,另一端稱為棧底。

棧中的數據元素遵守后進先出LIFO(Last In First Out)的原則。 ?

壓棧:棧的插入操作叫做進棧/壓棧/入棧,入數據在棧頂

出棧:棧的刪除操作叫做出棧。出數據在棧頂

下面結合圖片給出具體的理解:

?

棧的使用?

?

下面給出代碼的運用加以理解:?

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()); ? // 獲取棧中有效元素個數---> 4System.out.println(s.peek()); ? // 獲取棧頂元素---> 4s.pop(); ? // 4出棧,棧中剩余1 ? 2 ? 3,棧頂元素為3System.out.println(s.pop()); ? // 3出棧,棧中剩余1 2 ? 棧頂元素為3if(s.empty()){System.out.println("棧空");}else{System.out.println(s.size());}
}

棧的模擬實現?

?

從上圖中可以看到,Stack繼承了Vector,Vector和ArrayList類似,都是動態的順序表,不同的是Vector是線程安全的。?

Stack的具體模擬實現如下:?

public class MyStack {public int[] elem;public int usedSize;public static final int DEFAULT_CAPACITY = 10;public MyStack() {this.elem = new int[DEFAULT_CAPACITY];}//壓棧public void push(int val) {if (isFull()) {this.elem = Arrays.copyOf(elem,2*elem.length);}elem[usedSize++] = val;}public boolean isFull() {return usedSize == elem.length;}//出棧public int pop() {if (isEmpty()) {throw new EmptyStackException("棧為空!!!!");}int oldVal = elem[usedSize-1];usedSize--;//elem[usedSize] = null;return oldVal;}public boolean isEmpty() {return usedSize == 0;}public int peek() {if(isEmpty()) {throw new EmptyStackException("棧為空!!!!!");}return elem[usedSize - 1];}
}

棧的應用場景

改變元素的序列 ?

如上圖兩題在棧的理解上,解決可得選項為 C 和 B.

將遞歸轉化為循環?

這里給大家提供一個例子:逆序打印鏈表?

// 遞歸方式
void printList(Node head){if(null != head){printList(head.next);System.out.print(head.val + " ");}
}// 循環方式
void printList(Node head){if(null == head){return;}Stack<Node> s = new Stack<>();// 將鏈表中的結點保存在棧中Node cur = head;while(null != cur){s.push(cur);cur = cur.next;}
// 將棧中的元素出棧while(!s.empty()){System.out.print(s.pop().val + " ");}
}

這里還有一些練習的題目:如果想更深入了解棧的相關機理,可以嘗試做一做

1.括號匹配

2.逆波蘭表達式?

3.出棧入棧次序匹配?

4.最小棧?

這里提出一個思考題:棧、虛擬機棧、棧幀有什么區別呢?

:棧是一種數據結構,具有后進先出(LIFO)的特性,用于存儲函數調用、局部變量等數據。在計算機中,棧通常是指操作系統管理的內存區域,用于存儲函數調用時的參數、返回地址、局部變量等。

虛擬機棧:虛擬機棧是指在Java虛擬機中用來執行Java方法的內存區域,用于存儲方法的局部變量、操作數棧、動態鏈接、方法出口等信息。虛擬機棧與操作系統的棧類似,但是在Java虛擬機中,每個線程都有自己的虛擬機棧,用于執行方法時的數據存儲。

棧幀:棧幀是指在方法調用時壓入虛擬機棧中的數據結構,用于存儲方法的局部變量、操作數棧、動態鏈接、方法出口等信息。每個方法調用都會創建一個對應的棧幀,用于存儲該方法執行時需要的數據。棧幀是虛擬機棧中的一個重要組成部分,用于支持方法的執行和調用。

隊列(Queue)?

隊列的定義?

隊列:只允許在一端進行插入數據操作,在另一端進行刪除數據操作的特殊線性表,

隊列具有先進先出FIFO(First In First Out)

入隊列:進行插入操作的一端稱為隊尾(Tail/Rear)

出隊列:進行刪除操作的一端稱為隊頭 (Head/Front) ?

?

隊列的使用?

在Java中,Queue是個接口,底層是通過鏈表實現的。 ?

?

注意:

Queue是個接口,在實例化時必須實例化LinkedList的對象(因為LinkedList實現了Queue接口)

public static void main(String[] args) {Queue<Integer> q = new LinkedList<>();q.o?er(1);q.o?er(2);q.o?er(3);q.o?er(4);q.o?er(5); ? ? ? ? ? ? ? ? ?// 從隊尾入隊列System.out.println(q.size());System.out.println(q.peek()); ?// 獲取隊頭元素q.poll();System.out.println(q.poll()); ?// 從隊頭出隊列,并將刪除的元素返回if(q.isEmpty()){System.out.println("隊列空");}else{System.out.println(q.size());}
}

隊列模擬實現?

隊列中既然可以存儲元素,那底層肯定要有能夠保存元素的空間

常見的空間類型有兩種:順序結構 和 鏈式結構。

思考題:隊列的實現使用順序結構還是鏈式結構好??

順序結構:

優點:順序結構的隊列使用數組實現,插入和刪除操作的時間復雜度為O(1),在空間上比較節省。

缺點:在插入和刪除元素時,需要移動其他元素,可能會導致性能下降。而且順序結構的隊列有容量限制,當隊列滿時需要進行擴容操作。

鏈式結構:

優點:鏈式結構的隊列使用鏈表實現,插入和刪除操作的時間復雜度為O(1),不需要移動其他元素。而且鏈式結構的隊列沒有容量限制,可以動態增加或減少元素。

缺點:鏈式結構的隊列在內存占用上比順序結構更大,因為每個節點都需要額外的指針指向下一個節點。

總結:如果對內存占用要求比較高,且隊列的大小是固定的,可以選擇順序結構實現隊列;如果對插入和刪除操作的性能要求比較高,且隊列的大小是動態變化的,可以選擇鏈式結構實現隊列。

隊列實現場景圖:

?

下面給出模擬實現的代碼(僅供參考):?

public class Queue {// 雙向鏈表節點public static class ListNode{ListNode next;ListNode prev;int value;ListNode(int value){this.value = value;}}ListNode ?rst; ? // 隊頭ListNode last; ? ?// 隊尾int size = 0;// 入隊列---向雙向鏈表位置插入新節點public void o?er(int e){ListNode newNode = new ListNode(e);if(?rst == null){?rst = newNode;// last = newNode;}else{last.next = newNode;newNode.prev = last;// last = newNode;}last = newNode;size++;}// 出隊列---將雙向鏈表第一個節點刪除掉public int poll(){// 1. 隊列為空// 2. 隊列中只有一個元素----鏈表中只有一個節點---直接刪除// 3. 隊列中有多個元素---鏈表中有多個節點----將第一個節點刪除int value = 0;if(?rst == null){return null;}else if(?rst == last){last = null;?rst = null;}else{value = ?rst.value;?rst = ?rst.next;?rst.prev.next = null;?rst.prev = null;}--size;return value;}// 獲取隊頭元素---獲取鏈表中第一個節點的值域public int peek(){if(?rst == null){return null;}return ?rst.value;}public int size() {return size;}public boolean isEmpty(){return ?rst == null;}
}

循環隊列?

?

數組下標循環的小技巧

1. 下標最后再往后(o?set 小于 array.length): index = (index + o?set) % array.length ?

?

2. 下標最前再往前(o?set 小于 array.length): index = (index + array.length - o?set) % array.length?

?

如何區分空與滿?

1. 通過添加 size 屬性記錄?

2. 保留一個位置

3. 使用標記 ?

?

感興趣的可以試試這道相關題目:設計循環隊列?

雙端隊列 (Deque)?

雙端隊列(deque)是指允許兩端都可以進行入隊和出隊操作的隊列,deque 是 “double ended queue” 的簡稱。 那就說明元素可以從隊頭出隊和入隊,也可以從隊尾出隊和入隊。 ?

Deque是一個接口,使用時必須創建LinkedList的對象。?

?

在實際工程中,使用Deque接口是比較多的,棧和隊列均可以使用該接口。

這里給出兩種實現方式

Deque stack = new ArrayDeque<>();//雙端隊列的線性實現

Deque queue = new LinkedList<>();//雙端隊列的鏈式實現?

泛型

泛型:就是適用于許多許多類型。從代碼上講,就是對類型實現了參數化。?

主要目的:就是指定當前的容器,要持有什么類型的對象。讓編譯器去做檢查。?

在編譯的過程當中,將所有的T替換為Object這種機制,這種機制稱為:擦除機制。 ?

class MyArray<T> {public T[] array = (T[])new Object[10];//1public T getPos(int pos) {return this.array[pos];}public void setVal(int pos,T val) {this.array[pos] = val;}
}
public class TestDemo {public static void main(String[] args) {MyArray<Integer> myArray = new MyArray<>();//2myArray.setVal(0,10);myArray.setVal(1,12);int ret = myArray.getPos(1);//3System.out.println(ret);myArray.setVal(2,"bit");//4}
}

對上述代碼進行一個說明:

1. 類名后的代表占位符,表示當前類是一個泛型類

了解:【規范】類型形參一般使用一個大寫字母表示,

常用的名稱有:

E 表示 Element

K 表示 Key

V 表示 Value

N 表示 Number

T 表示 Type

S, U, V 等等 - 第二、第三、第四個類型

2. 注釋1處,不能new泛型類型的數組 ,說明:

T[] ts = new T[5];//是不對的

3. 注釋2處,類型后加入 指定當前類型

4. 注釋3處,不需要進行強制類型轉換

5. 注釋4處,代碼編譯報錯,此時因為在注釋2處指定類當前的類型,此時在注釋4處,編譯器會在存放元素的時 候幫助我們進行類型檢查。

此處只對泛型做一個簡單的介紹,不作過多解釋,理解就好......??

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

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

相關文章

ddpm Denoising Diffusion Probabilistic Model 學習筆記

目錄 Stable Diffusion 文章的貢獻抽象出來就兩個 潛空間上做擴散生成 ddpm(Denoising Diffusion Probabilistic Model)學習筆記 算法原理 unet預測噪聲 unet推理過程 重參數化技巧 &#xff08;1&#xff09;利用前一時刻的 xt-1 得到任意時刻的噪聲圖片 xt&#xff…

LeetCode2215找出兩數組的不同

題目描述 給你兩個下標從 0 開始的整數數組 nums1 和 nums2 &#xff0c;請你返回一個長度為 2 的列表 answer &#xff0c;其中&#xff1a;answer[0] 是 nums1 中所有 不 存在于 nums2 中的 不同 整數組成的列表。answer[1] 是 nums2 中所有 不 存在于 nums1 中的 不同 整數組…

Linux poweroff命令教程:如何實現一鍵關機(附實例詳解和注意事項)

Linux poweroff命令介紹 poweroff命令是用來關閉系統的。當你執行這個命令時&#xff0c;它會發送一個信號給系統&#xff0c;告訴系統關閉所有的進程&#xff0c;然后關閉系統。這個命令非常有用&#xff0c;特別是在你需要遠程關閉系統&#xff0c;或者你的系統沒有圖形用戶…

Autosar架構

藍框那種叫component&#xff0c;綠框的叫function cluster。 接口 有三種接口&#xff0c;RTE跟SWC之間鏈接的叫Autosar Interface&#xff0c;RTE跟BSW的Components鏈接是Standardized Interface&#xff0c;RTE跟BSW的services鏈接的是Standardized Autosar Interface。 St…

項目部署到線上proxytable代理失效nginx報404的問題

我的項目是在vue的config文件夾中的index.js中配置了接口地址 &#xff0c;本地跑的時候都能訪問&#xff0c;放到線上就報404&#xff1b; module.exports {dev: {// PathsassetsSubDirectory: static,assetsPublicPath: /,proxyTable: {/xxx: {target: http://xxxxxxxx:xxx…

分享四種CAD圖紙加密方法,嚴防盜圖

在數字化時代&#xff0c;cad圖紙的盜用和非法傳播問題日益突出。對于企業和設計師來說&#xff0c;保護設計成果的安全性和原創性&#xff0c;采取有效的cad加密方法至關重要。本文將分享四種cad加密方法&#xff0c;幫助您嚴防盜圖&#xff0c;保護圖紙安全。 使用cad軟件內…

網絡協議的分類

1.概要 網絡協議可以分為三類&#xff1a; 封裝協議路由協議功能類協議 2.分類說明 OSPF報文直接調用_ IP協議__協議進行封裝&#xff0c;以目的地址_244.0.0.5 __發送到所有的OSPF路由器? 244.0.0.1 所有主機&#xff1b;244.0.0.2 所有路由器&#xff1b;244.0.0.6 指定…

【前端每日一題】day5

JS 實現繼承的幾種方式 在JavaScript中&#xff0c;實現繼承的幾種方式包括原型鏈繼承、構造函數繼承、組合繼承、原型式繼承、寄生式繼承和組合式繼承。 原型鏈繼承&#xff1a; function Parent() {this.name Parent; } Parent.prototype.sayHello function() {console.…

當它還是幼生期的時候,及早離開它!

當我們有豐富的精神生活時&#xff0c;充實的知識吸收儲備時&#xff0c;為自己的每一點進步而欣慰時&#xff0c;我們就不會有失敗的憂慮。也不會有孤單的自憐。 沒有人是弱者&#xff0c;每個人都有自己活著的方式&#xff0c;當你內心強大時&#xff0c;你會尊重每一個“弱者…

Vue+springboot的批量刪除功能

vue前臺 <div style"margin-bottom: 10px"><el-button type"primary" plain click"handleAdd">新增</el-button><el-button click"delBatch" type"danger" plain style"margin-left: 5px"…

Spring Cloud 背后技術詳解

Spring Cloud 是基于 Spring Boot 的一套微服務架構解決方案。它為開發者提供了一系列的工具&#xff0c;用于快速構建分布式系統中的一些常見模式&#xff08;例如配置管理、服務發現、斷路器等&#xff09;。Spring Cloud 利用 Spring Boot 的自動配置和獨立運行能力&#xf…

C語言例題41、八進制轉換為十進制

#include<stdio.h>void main() {int x;printf("請輸入一個8進制整數&#xff1a;");scanf("%o", &x);printf("轉換成十進制后的整數為%d\n", x); }運行結果&#xff1a; 本章C語言經典例題合集&#xff1a;http://t.csdnimg.cn/FK0Qg…

Java基礎(33)Java Web攔截器作用和用法

Java Web攔截器&#xff08;Interceptor&#xff09;是Java Web開發中一個重要的概念&#xff0c;它允許開發者在處理HTTP請求和響應之前或之后執行特定的代碼&#xff0c;從而實現如權限檢查、日志記錄、事務管理等功能。攔截器可以作用于Java EE的Servlet、Spring框架、Strut…

redis試題按知識點歸類(四)

十六、實戰應用 1.如何使用 Redis 存儲用戶會話&#xff1f; 2.Redis 在電子商務平臺中的應用是什么&#xff1f; 3.如何使用 Redis 進行實時數據分析&#xff1f; 十七、面試題綜合 1.描述一次你解決 Redis 性能問題的經歷。 2.你如何理解 Redis 中的“單線程”模型&…

Java入門基礎學習筆記21——Scanner

在程序中接收用戶通過鍵盤輸入的數據&#xff1a; 需求&#xff1a; 請在程序中&#xff0c;提示用戶通過鍵盤輸入自己的姓名、年齡、并能在程序中收到這些信息&#xff0c;怎么解決&#xff1f; Java已經寫好了實現程序&#xff0c;我們調用即可。 API&#xff1a;Applicat…

2024 年中國大學生程序設計競賽全國邀請賽(鄭州)暨第六屆CCPC河南省大學生程序設計競賽 problem K. 樹上問題

//先找一個美麗的樹&#xff0c;然后遍歷樹找節點,分析是否符合條件。 //畫幾個圖&#xff0c;思考下。 #include<bits/stdc.h> using namespace std; #define int long long const int n1e611; int a,b,c[n],d,l,r,k,w,an; vector<int>t[n]; void dfs(int x,int…

MLT剪輯sample

#include <framework/mlt.h> int main(int argc, char **argv) { // 初始化MLT mlt_factory factory mlt_factory_init(NULL); // 加載素材&#xff08;這里假設我們有一個名為"video.mp4"的視頻文件&#xff09; mlt_profile profile mlt_prof…

什么是頁分裂、頁合并?

數據組織方式 在InnoDB存儲引擎中&#xff0c;表數據都是根據主鍵順序組織存放的&#xff0c;這種存儲方式的表稱為索引組織表(index organized table IOT)。 行數據&#xff0c;都是存儲在聚集索引的葉子節點上的。而我們之前也講解過InnoDB的邏輯結構圖&#xff1a; 在I…

61、內蒙古工業大學、內蒙科學技術研究院:CBAM-CNN用于SSVEP - BCI的分類方法[腦機二區還是好發的]

前言&#xff1a; 之前寫過一篇對CBAM模型改進的博客&#xff0c;在CBAM中引入了ECANet結構&#xff0c;對CBAM中的CAM、SAM模塊逐一改進&#xff0c;并提出ECA-CBAM單鏈雙鏈結構&#xff0c;我的這個小的想法已經被一些同學實現了&#xff0c;并進行了有效的驗證&#xff0c;…

快速對比 找出2個名單不同之處

import pandas as pd# 讀取兩個Excel文件 df1 pd.read_excel(1.xlsx) df2 pd.read_excel(2.xlsx)# 檢查兩個DataFrame的列是否相同 if list(df1.columns) ! list(df2.columns):print("兩個Excel文件的列不一致。")print("文件1的列&#xff1a;", df1.co…