1. 程式人生 > >java數據結構和算法02(棧)

java數據結構和算法02(棧)

復制 結構 出了 很多 棧的實現 pack args ati main

  什麽叫做棧(Stack)呢?這裏的棧和jvm的java棧可不是一個東西。。。

  棧作為一種數據結構,我感覺棧就類似一種接口,實現的話有很多種,比如用數組、集合、鏈表都可以實現棧的功能,棧最大的特點就是先進後出,可以想象一下放羽毛球的盒子怎麽放進羽毛球和拿出來羽毛球,我們把放進羽毛球的動作就叫做壓棧或者入棧(push),拿出羽毛球的動作就叫做彈棧或出棧(pop)

技術分享圖片

  其實在java中已經有個棧的實現了,就是Stack,我們簡單用一下:

package com.wyq.thread;

import java.util.Stack;

public class MyStack {
    public static void main(String[] args) {
        Stack<Object> stack = new Stack<Object>();
        stack.push("老王");
        stack.push(123);
        stack.push(false);
        stack.push(‘a‘);
        System.out.println(stack.toString());
        
        for (int i = 0; i < 4; i++) {
            System.out.println(stack.pop());
        }
    }
}

技術分享圖片

 這個Stack默認使用集合實現的,這個類是繼承了Vector,而Vector這個類就是一個集合,實現了List接口的,而且我們還知道這個Vector這個類是線程安全的,每個方法都加了synchronized關鍵字,所以也就是說效率不會怎麽高。我們可以試試用數組來自己簡單實現一個棧,可能就對棧這種數據結構有點了解了,為什麽棧是先進後出的呢?假如我們要實現怎麽才能實現這種進出方式呢?

  在我們實現的棧中我不會實心擴容的,因為邏輯一多就容易弄混,但是我還是將擴容的原理說一下:

  假如有一個最大容量是20數組A,還會有個負載因子一般是0.75,這個負載因子幹什麽用的呢?

技術分享圖片

  這個0.75就是a/b得出來的,雖然可以修改這個0.75這個值,但是據說0.75是最穩定的最好不要修改這個值;

  當我們往A數組中放數據,當放了20*0.75=15個數據之後,此時這個數組就會收到一個警報,快裝滿了,趕緊想想辦法,於是啊,又創建出了一個比20更大的數組,假設是40容量的數組B,然後我們就把A數組中的所有數據都復制到B數組中,再把指向數組A的引用修改為指向數組B的引用就ok了,如下圖所示:

技術分享圖片

  我們自己實現的棧為了簡潔起見,越簡潔越好,就不弄這些花裏胡哨的東西了,怎麽簡單怎麽來,想進行擴容的小夥伴可以自己添加擴容方法;

  順便說一個簡單的東西,++n和n++,--n和n--的區別:比如Value = ++n,這表示n先+1再賦值給value,比如value = n++,這就表示n先賦值給value,然後n再+1

package com.wyq.thread;

import java.util.Arrays;

public class MyStack {
    private Object[] arr;
    //數組中最大的容量
    private int maxlength;
    //指向棧頂的元素,也就是指向數組最後一個位置的元素
    private int top;
    
    //調用有參構造,默認是10個容量的數組
    public MyStack(){
        this(10);
    }
    public MyStack(int len){
        this.maxlength = len;
        arr = new Object[maxlength];
        top = -1;//因為剛開始數組中沒有數據,我們把top=-1表示數組中沒有元素
    }
    //壓棧,首先要保證top的值不能大於最大的索引,不然數據都放到數組外面了
    //要想將一個數據丟進棧中,先將top往後往後移動一個位置,然後在這個位置放入數據
    public void push(Object obj){
        if (top<maxlength-1) {
            arr[++top] = obj;
            
        }
    }
    //彈棧,首先找到棧頂的元素,這個peek()方法就在下面,將這個棧頂的元素返回,然後經數組最後一個數據變為null
    //最後就是將top往前移動一個位置,確保top始終指向的是棧頂元素(數組最後一個元素)
    public Object pop(){
        Object peek = peek();
        arr[top--]=null;
        return peek;
    }
    //查詢棧頂的數據,註意此時並沒有彈棧,我們只是想看看棧頂是什麽東西
    public Object peek(){
        return arr[top];
    }
    //重寫toString方法,更好的進行展示棧中的數據
    @Override
    public String toString() {
        return Arrays.toString(arr)+"]";
    }
    public static void main(String[] args) {
        MyStack stack = new MyStack();
        stack.push("老王");
        stack.push(123);
        stack.push(false);
        stack.push(‘a‘);
        System.out.println(stack.toString());
        
        for (int i = 0; i < 4; i++) {
            System.out.println(stack.pop());
        }
    }
}

  感覺比上一篇的array容易不少啊.....

java數據結構和算法02(棧)