欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java棧和基礎隊列的實現(xiàn)詳解

 更新時間:2022年02月14日 14:54:58   作者:Word碼鴨  
這篇文章主要介紹了Java數(shù)據(jù)結構中的棧與隊列,在Java的時候,對于棧與隊列的應用需要熟練的掌握,這樣才能夠確保Java學習時候能夠有扎實的基礎能力。本文小編就來詳細說說Java中的棧與隊列,需要的朋友可以參考一下

棧和隊列:都是線性表,都是基于List基礎上的實現(xiàn)

線性表:數(shù)組,鏈表,字符串,棧,隊列

元素按照一條“直線”排列,線性表這個結構中,一次添加單個元素

棧(stack)

一種特殊的線性表,其只允許在固定的一端進行插入和刪除元素操作。進行數(shù)據(jù)插入和刪除操作的一端稱為棧頂,另一端稱為棧底。棧中的數(shù)據(jù)元素遵守后進先出LIFO(Last In First Out)的原則。

20191212190125865.gif (1920×1080)

20191212204731172.gif (1920×1080)

棧支持的三個核心操作:

  • 入棧push
  • 出棧pop
  • 返回棧頂元素peek  

棧的常見實際應用:

  • 無處不在的撤銷操作undo,一般任意的編輯器都使用 ctrl + z 操作,其實本質就是每次操作一次 ctrl + z 就是一次棧的pop
  • 瀏覽器的前進后退,瀏覽器維護了一個棧結構A->B->C,此時頁面停留在C,想要回到頁面B,點擊后退鍵頭就相當于將C出棧,此時的棧頂就是B
  • 在開發(fā)程序中的“調用棧”操作系統(tǒng)棧底層就是棧的實現(xiàn)

棧的實現(xiàn)

棧是一種線性表,所以實現(xiàn)它即可使用數(shù)組,也可以使用鏈表

  • 基于數(shù)組實現(xiàn)的棧—順序棧(棧頂實際就是數(shù)組尾部,在數(shù)組尾部添加和刪除)
  • 基于鏈表實現(xiàn)的棧—鏈式棧(鏈表的頭插和尾插)

在數(shù)組尾部進行刪除和插入的時間復雜度為O(1),所以用數(shù)組實現(xiàn)棧是我們的首選

實現(xiàn)代碼:

//基于數(shù)組實現(xiàn)的棧
public class MyStack<E> {
    private int size;//數(shù)組長度
    //實際存儲數(shù)據(jù)的動態(tài)數(shù)組
    private List<E> data = new ArrayList<>();
    
    //入棧,默認尾插
    public void push(E val){
        data.add(val);
        size ++;
    }
    
    //彈出棧頂元素,返回棧頂?shù)闹?
    public E pop(){
        if(isEmpty()){
            //棧為空
            throw new NoSuchElementException("stack is empty!cannot pop!");
        }
        //刪元素
       E val =  data.remove(size-1);
        size--;
        return val;
        //上面三句等同于return data.remove(size-1);
    }
    
    //返回棧頂元素,但不出棧
    public E peek(){
        if(isEmpty()){
            throw new NoSuchElementException("stack is empty!cannot peek");
        }
        return data.get(size-1);
    }
    
    // 判斷當前棧是否為空
    public boolean isEmpty() {
        return size == 0;
    }
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < size; i++) {
            sb.append(data.get(i));
            if (i != size - 1) {
                // 此時還沒到棧頂,還沒到數(shù)組末尾
                sb.append(", ");
            }
        }
        sb.append("] top");
        return sb.toString();
    }
}
 
//--------------------------
//測試類·
public class StackTest {
    public static void main(String[] args) {
        MyStack<Integer> myStack = new MyStack<>();
        myStack.push(1);
        myStack.push(3);
        myStack.push(5);
        System.out.println(myStack);
        System.out.println(myStack.pop());//刪除棧頂
        System.out.println(myStack.peek());//輸出棧頂,此時棧頂為3
        System.out.println(myStack.isEmpty());
    }
}

//輸出結果:
[1, 3, 5] top
5
3
false

隊列

只允許在一端進行插入數(shù)據(jù)操作,在另一端進行刪除數(shù)據(jù)操作的特殊線性表,隊列遵循先進先出FIFO(First In First Out)的原則 :進行插入操作的一端稱為隊尾(Tail/Rear) 出隊列:進行刪除操作的一端稱為隊頭

其實隊列的定義很簡單,就相當于我們現(xiàn)實生活的排隊購物,先排隊的人先結賬,也就先離開

隊列的子類比棧要復雜一些,它有:

  • 基礎隊列—FIFO
  • 基于優(yōu)先級的隊列—按照優(yōu)先級大小出隊
  • 循環(huán)隊列—基于數(shù)組實現(xiàn)的
  • 雙端隊列

無論是哪種隊列,都必須支持三個核心操作:

  • 入隊—offer
  • 出隊—poll
  • 返回隊首元素—peek  

基礎隊列的實現(xiàn) 

  • 基于數(shù)組實現(xiàn)的隊列—順序隊列
  • 基于鏈表實現(xiàn)的隊列—鏈式隊列

由于隊列是從隊尾插入,隊首出隊,而在數(shù)組頭部刪除的時間復雜度為O(n),此時我們用鏈表會更好一些。而且無論實現(xiàn)哪種隊列都需要覆寫三個基本操作,因此我們將隊列設計為接口

實現(xiàn)代碼:

public interface Queue<E> {
    // 入隊
    void offer(E val);
    // 出隊
    E poll();
    // 返回隊首元素
    E peek();
    // 判斷隊列是否為空
    boolean isEmpty();
}
 
 //基于鏈表實現(xiàn)的基礎隊列
public class MyQueue<E> implements Queue<E> {
    // 鏈表的每個節(jié)點
    // ------------------------------
    //內部類
    private class Node {
        E val;
        Node next;
        public Node(E val) {
            this.val = val;
        }
    }
    // ------------------------------
    // 當前隊列中的元素個數(shù)
    private int size;
    // 隊首
    private Node head;
    // 隊尾
    private Node tail;
    @Override
    public void offer(E val) {
        Node node = new Node(val);
        if (head == null) {
            // 此時鏈表為空
            head = tail = node;
        }else {
            tail.next = node;
            tail = node;
        }
        size ++;
    }
 
    @Override
    public E poll() {
        if (isEmpty()) {
            throw new NoSuchElementException("queue is empty!cannot poll!");
        }
        E val = head.val;
        Node node = head;
        head = head.next;
        // 將原來頭節(jié)點脫鉤
        node.next = null;
        size --;
        return val;
    }
 
    @Override
    public E peek() {
        if (isEmpty()) {
            throw new NoSuchElementException("queue is empty!cannot peek!");
        }
        return head.val;
    }
 
    @Override
    public boolean isEmpty() {
        return size == 0;
    }
 
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("front [");
        // 鏈表的遍歷
        for (Node x = head;x != null;x = x.next) {
            sb.append(x.val);
            if (x.next != null) {
                // 還沒走到鏈表尾部
                sb.append(", ");
            }
        }
        sb.append("]");
        return sb.toString();
    }
}
 
//測試類
public class QueueTest {
    public static void main(String[] args) {
        Queue<Integer> queue = new MyQueue<>();
        queue.offer(1);
        queue.offer(3);
        queue.offer(5);
        System.out.println(queue);
    }
}

作為初學者,我們不能小瞧任何簡單的數(shù)據(jù)結構與算法,基礎的數(shù)據(jù)結構往往作為高階數(shù)據(jù)結構的一部分來應用,萬丈高樓平地起,平時要多加練習,我們一起加油!

到此這篇關于Java棧和基礎隊列的實現(xiàn)詳解的文章就介紹到這了,更多相關Java 棧和基礎隊列內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Kotlin基本類型自動裝箱出現(xiàn)問題解決辦法

    Kotlin基本類型自動裝箱出現(xiàn)問題解決辦法

    這篇文章主要介紹了Kotlin基本類型自動裝箱出現(xiàn)問題解決辦法的相關資料,希望通過本文能幫助到大家,讓大家遇到這樣的問題順利解決,需要的朋友可以參考下
    2017-10-10
  • 超好用的Java工具類庫Hutool用法詳解

    超好用的Java工具類庫Hutool用法詳解

    Hutool是一個小而全的Java工具類庫,通過靜態(tài)方法封裝,降低相關API的學習成本,提高工作效率,下面就跟隨小編一起來學習一下Hutool的具體用法吧
    2023-09-09
  • struts2中simple主題下<s:fieldError>標簽默認樣式的移除方法

    struts2中simple主題下<s:fieldError>標簽默認樣式的移除方法

    這篇文章主要給大家介紹了關于struts2中simple主題下<s:fieldError>標簽默認樣式的移除方法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧
    2018-10-10
  • Java求出任意數(shù)字的各個位數(shù)之和方式

    Java求出任意數(shù)字的各個位數(shù)之和方式

    這篇文章主要介紹了Java求出任意數(shù)字的各個位數(shù)之和方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java保證對象在內存中唯一性的實現(xiàn)方法

    java保證對象在內存中唯一性的實現(xiàn)方法

    這篇文章主要介紹了java如何保證對象在內存中的唯一性,如果創(chuàng)建多個對象的話,可能會引發(fā)出各種各樣的問題,這時,就需要我們保證這個對象在內存中的唯一性,需要的朋友可以參考下
    2019-06-06
  • MyBatis插入Insert、InsertSelective的區(qū)別及使用心得

    MyBatis插入Insert、InsertSelective的區(qū)別及使用心得

    這篇文章主要介紹了MyBatis插入Insert、InsertSelective的區(qū)別及使用心得,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java分布式學習之Kafka消息隊列

    Java分布式學習之Kafka消息隊列

    Kafka是由Apache軟件基金會開發(fā)的一個開源流處理平臺,由Scala和Java編寫。Kafka是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),它可以處理消費者在網(wǎng)站中的所有動作流數(shù)據(jù)
    2022-07-07
  • SpringBoot實現(xiàn)登錄校驗(JWT令牌)

    SpringBoot實現(xiàn)登錄校驗(JWT令牌)

    JWT全稱為JSON Web Token,是一種用于身份驗證的開放標準,本文主要介紹了SpringBoot實現(xiàn)登錄校驗(JWT令牌),具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • java的java.security.egd源碼解讀

    java的java.security.egd源碼解讀

    這篇文章主要為大家介紹了java的java.security.egd源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • jvm雙親委派 vs 破壞雙親委派理解加載器的權責分配

    jvm雙親委派 vs 破壞雙親委派理解加載器的權責分配

    這篇文章主要為大家介紹了jvm雙親委派 vs 破壞雙親委派對比來理解加載器的權責分配,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10

最新評論