Java的棧與隊(duì)列實(shí)現(xiàn)代碼解析
棧的概念(Stack)
棧是常見的線性數(shù)據(jù)結(jié)構(gòu),棧的特點(diǎn)是以先進(jìn)后出的形式,后進(jìn)先出,先進(jìn)后出,分為棧底和棧頂
棧應(yīng)用于內(nèi)存的分配,表達(dá)式求值,存儲(chǔ)臨時(shí)的數(shù)據(jù)和方法的調(diào)用等。
例如這把槍,第一發(fā)子彈是最后發(fā)射的,第一發(fā)子彈在棧底,而最新安裝上去的子彈在棧的頂部,只有將上面的子彈打完(棧頂?shù)臄?shù)據(jù)走完),最后一發(fā)子彈才會(huì)射出

棧的實(shí)現(xiàn)
棧的實(shí)現(xiàn)是基于簡(jiǎn)單的數(shù)組形成的,我們可以將它想象成連續(xù)的數(shù)組,而棧的順序是由后放到前放

模擬實(shí)現(xiàn)棧的方法:push(放入一個(gè)元素到棧中)
pop(提取棧頂?shù)囊粋€(gè)元素,并將在其棧中消除)
peek(查看棧頂?shù)脑?
size(查看棧中的大小)
empty(棧中是否為空)
full(棧是否滿了)
代碼
import java.util.Arrays;
public class MyStack implements IStack {
private int[] elem;
private int top;//數(shù)組的棧頂,以及數(shù)組棧中存放元素的數(shù)量
private static final int DEFAULT_CAPACITY = 10;//這里是初始容量
public MyStack() {
elem = new int[DEFAULT_CAPACITY];
top = -1;//數(shù)組下標(biāo)從0開始
}
@Override
public void push(int item) {
if (full()) {
//如果滿了就擴(kuò)容
elem = Arrays.copyOf(elem, 2 * elem.length);
}
elem[++top] = item;
}
@Override
public int pop() throws RuntimeException {
try {
if (empty()) {
throw new RuntimeException("棧為空");
}
} catch (RuntimeException e) {
e.printStackTrace();
}
return elem[top--];//return返回后刪除棧頂?shù)脑?
}
@Override
public int peek() {
if (empty()) {
throw new RuntimeException("棧為空");
}
return elem[top];//返回棧頂元素
}
@Override
public int size() {
return top+1;//去除數(shù)組0
}
@Override
public boolean empty() {
return top == -1;
}
@Override
public boolean full() {
return top == elem.length;//count==當(dāng)前的elem的總長(zhǎng)度為true
}
}隊(duì)列(Queue)
隊(duì)列是由先進(jìn)先出的線性數(shù)據(jù)結(jié)構(gòu),采用的是先進(jìn)先出,后進(jìn)后出,如果要插入元素的話就是從入隊(duì)尾巴方向插入,而刪除作為出隊(duì)要在頭尾刪除。

隊(duì)列的方法

模擬實(shí)現(xiàn)隊(duì)列(雙鏈表實(shí)現(xiàn))
public class MyQueue implements IQueue{
static class Queue{
public int elem;
public Queue next;
public Queue prev;
public Queue(int elem) {
this.elem = elem;
}
}
public Queue head;
public Queue last;
public int size=0;
@Override
public void offer(int val) {
Queue queue = new Queue(val);
if (this.head == null) {
this.head = queue;
this.last = queue;
++size;
return;
}
this.last.next=queue;
this.last.prev=this.head;
this.last=last.next;
++size;
}
@Override
public int poll() {
if(this.head==null){
throw new RuntimeException("沒有要丟掉的隊(duì)列");
}
Queue cur =this.head;
if(this.head.next==null){
return -1;
}
this.head=this.head.next;
this.head.prev=null;
size--;
return cur.elem;
}
@Override
public int peek() {
if(this.head!=null){
return this.head.elem;
}
return 0;
}
@Override
public int size() {
return size;
}
}循環(huán)隊(duì)列(循環(huán)數(shù)組實(shí)現(xiàn))
數(shù)組實(shí)現(xiàn)隊(duì)列的循環(huán)需要引入一個(gè)公式(目前的下標(biāo)值+1)%當(dāng)前數(shù)組的長(zhǎng)度
(index+1)%array.length,下標(biāo)值從0開始少一個(gè)數(shù),當(dāng)index+1就是當(dāng)前的總長(zhǎng)度時(shí),公式后的值一定為下標(biāo)0。

private int[] array;
private int front;
private int rear;
public MyCircularQueue(int k) {
array=new int[k+1];
front=0;//初始位置
rear=0;
}
public boolean enQueue(int value) {
//入列
if(isFull()){
//這里如果容量已經(jīng)滿了,需要先刪除后在進(jìn)行插入
return false;
}
array[rear]=value;//rear下標(biāo)獲取元素
rear=(rear+1)%array.length;//rear最終循環(huán)為0下標(biāo)
return true;
}
public boolean deQueue() {
//出列
if(isEmpty()){
//為空返回false
return false;
}
front=(front+1)%array.length;//front只需要往后走
return true;
}
public int Front() {
if(isEmpty()){
return -1;
}
return array[front];
}
public int Rear() {
if(isEmpty()){
return -1;
}
//這里三木操作符判斷是否為0如果為0,將rear回退到最后一個(gè)位置,不為0則-1
int temp = (rear==0)?array.length-1:rear-1;
return array[temp];
}
public boolean isEmpty() {
return front==rear;
}
public boolean isFull() {
return (rear+1)%array.length==front;
}
}用隊(duì)列實(shí)現(xiàn)棧

因?yàn)殛?duì)列是先進(jìn)先出的,而我們的棧是先進(jìn)后出的,兩種線性結(jié)構(gòu)的關(guān)系是顛倒的,一個(gè)隊(duì)列是不能完成的,我們需要兩個(gè)隊(duì)列互相工作來(lái)完成
輔助隊(duì)列先獲取數(shù)值,保證輔助隊(duì)列是最后一個(gè)拿到值的,然后將主隊(duì)列的值給到輔助隊(duì)列,在交換兩個(gè)隊(duì)列的數(shù)值,因?yàn)殛?duì)列關(guān)系先進(jìn)先出,每一次最后一個(gè)值就是隊(duì)列先出的數(shù)值
主隊(duì)列不為空,將主隊(duì)列的元素都poll出放到輔助棧中,使用一個(gè)tmp來(lái)將主隊(duì)列(這里主隊(duì)列已經(jīng)遍歷完)和輔助隊(duì)列交換

Queue<Integer> q1;//主隊(duì)列
Queue<Integer> q2;//輔助隊(duì)列
public MyStack() {
q1=new LinkedList<>();//構(gòu)造方法
q2=new LinkedList<>();
}
public void push(int x) {
q2.offer(x);
while(!q1.isEmpty()){//主隊(duì)列不為空,則將主隊(duì)列出列給到輔助隊(duì)列
q2.offer(q1.poll());
}
//走到這里主隊(duì)列是為空
Queue tmp=q1;
q1=q2;
q2=tmp;
//將兩個(gè)隊(duì)列交換
}
public int pop() {
return q1.poll();
}
public int top() {
return q1.peek();
}
public boolean empty() {
return q1.isEmpty();
}
}用棧來(lái)實(shí)現(xiàn)隊(duì)列

棧來(lái)實(shí)現(xiàn)隊(duì)列,棧是先進(jìn)后出的順序,而隊(duì)列是先進(jìn)先出的順序
將push都放到a棧中當(dāng)我們peek或者是要?jiǎng)h除的時(shí)候,我們都將a棧的元素pop給b棧,這樣b棧已經(jīng)有了我們的元素

但是我們還需要考慮的是丟掉元素后如果在一起添加元素到a棧呢,這里我們給一個(gè)條件,如果b的棧不為空時(shí),我們?nèi)匀挥胋棧的隊(duì)列
如果a為空,這兩個(gè)棧都是空的說(shuō)明沒有元素直接返回-1,如果a不為空的話且b沒有新的元素b繼續(xù)捕獲新的a棧中所有的元素

class MyQueue {
Stack<Integer> A;
Stack<Integer> B;
public MyQueue() {
A=new Stack<>();
B=new Stack<>();
}
public void push(int x) {
A.push(x);
}
public int pop() {
int check=peek();
B.pop();
return check;
}
public int peek() {
//先判斷b是否是空的,如果不是空的直接返回,是空才可以往下走
if(!B.isEmpty())return B.peek();
//因?yàn)閎還不是空的,所以不需要將a棧放到b中
if(A.isEmpty())return -1;
while(!A.isEmpty()){
B.push(A.pop());//將所有的a放到b中
}
return B.peek();
}
public boolean empty() {
return A.isEmpty()&&B.isEmpty();
//a和b都為空才為空
}
}總結(jié)
棧分為棧頂和棧底,最先進(jìn)的為棧底,最后進(jìn)的為棧頂。
隊(duì)列分為隊(duì)頭和隊(duì)尾,最先進(jìn)的為隊(duì)頭,最后進(jìn)的為隊(duì)尾。

到此這篇關(guān)于Java的棧與隊(duì)列實(shí)現(xiàn)代碼解析的文章就介紹到這了,更多相關(guān)java棧和隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java常見的數(shù)據(jù)結(jié)構(gòu)之棧和隊(duì)列詳解
- Java數(shù)據(jù)結(jié)構(gòu)之棧與隊(duì)列實(shí)例詳解
- Java數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之棧和隊(duì)列
- Java特性隊(duì)列和棧的堵塞原理解析
- Java數(shù)據(jù)結(jié)構(gòu)之鏈表、棧、隊(duì)列、樹的實(shí)現(xiàn)方法示例
- Java編程用兩個(gè)棧實(shí)現(xiàn)隊(duì)列代碼分享
- java 數(shù)據(jù)結(jié)構(gòu)中棧和隊(duì)列的實(shí)例詳解
相關(guān)文章
Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)
下面小編就為大家?guī)?lái)一篇Java 普通代碼塊靜態(tài)代碼塊執(zhí)行順序(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-08-08
Spring Boot使用模板freemarker的示例代碼
本篇文章主要介紹了Spring Boot使用模板freemarker的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-10-10
SpringBoot?基于?MongoTemplate?的工具類過程詳解
MongoDB是一個(gè)高性能,開源,無(wú)模式的文檔型數(shù)據(jù)庫(kù),是當(dāng)前NoSql數(shù)據(jù)庫(kù)中比較熱門的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類,需要的朋友可以參考下2023-09-09
spring boot項(xiàng)目沒有mainClass如何實(shí)現(xiàn)打包運(yùn)行
這篇文章主要介紹了spring boot項(xiàng)目沒有mainClass如何實(shí)現(xiàn)打包運(yùn)行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例
這篇文章介紹了在jmeter的beanshell中用java獲取系統(tǒng)當(dāng)前時(shí)間的簡(jiǎn)單實(shí)例,有需要的朋友可以參考一下2013-09-09

