1. 程式人生 > >Java程式碼實現順序棧和鏈式棧

Java程式碼實現順序棧和鏈式棧

Java程式碼實現順序棧和鏈式棧

棧(stack)又名堆疊,它是一種運算受限的線性表。其限制是僅允許在表的一端進行插入或者刪除運算。後進先出(Last In First Out)。

棧中的資料操作主要有push(壓入)和pop(彈出)操作。

實際上,棧就可以用陣列來實現,也可以用連結串列來實現。用陣列實現的叫做順序棧,用連結串列實現的叫做鏈式棧。

為了簡單起見,我們的棧不支援泛型。

順序棧

public class StackBasedArray implements StackInterface{

    private String[] values; // 儲存棧中元素的陣列
    private int capacity;// 棧的容量
    private int count;// 棧中已有資料個數

    // 初始化棧,容量確定。
    public StackBasedArray(int capacity) {
        this.values = new String[capacity];
        this.capacity = capacity;
        this.count = 0;
    }

    /**
     * 入棧操作
     *
     * @param value
     * @return
     */
    public Boolean push(String value) {
        // 陣列空間不夠了
        if (capacity == count) {
            return false;
        }
        values[count] = value;
        count++;
        return true;
    }

    /**
     * 出棧操作
     *
     * @return
     */
    public String pop() {
        // 棧為空,則直接返回null
        if (0 == count) {
            return null;
        }
        String tmp = values[count - 1];
        --count;
        return tmp;
    }

    @Override
    public String toString() {
        return "StackBasedArray{" +
                "values=" + Arrays.toString(values) +
                ", capacity=" + capacity +
                ", count=" + count +
                '}';
    }
}

測試程式碼:

        StackBasedArray as = new StackBasedArray(10);
        System.out.println(as);

        Boolean r1 = as.push("000");
        System.out.println(as + ",r1:" + r1);

        for (int i = 1; i < 11; i++) {
            boolean r2 = as.push("" + i + i + i);
            System.out.println(as + ",r2:" + r2);
        }

        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);
        System.out.println("as.pop():" + as.pop() + "," + as);

輸出結果:符合預期

StackBasedArray{values=[null, null, null, null, null, null, null, null, null, null], capacity=10, count=0}
StackBasedArray{values=[000, null, null, null, null, null, null, null, null, null], capacity=10, count=1},r1:true
StackBasedArray{values=[000, 111, null, null, null, null, null, null, null, null], capacity=10, count=2},r2:true
StackBasedArray{values=[000, 111, 222, null, null, null, null, null, null, null], capacity=10, count=3},r2:true
StackBasedArray{values=[000, 111, 222, 333, null, null, null, null, null, null], capacity=10, count=4},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, null, null, null, null, null], capacity=10, count=5},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, null, null, null, null], capacity=10, count=6},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, null, null, null], capacity=10, count=7},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, null, null], capacity=10, count=8},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, count=9},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=10},r2:true
StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=10},r2:false
as.pop():999,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=9}
as.pop():888,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=8}
as.pop():777,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=7}
as.pop():666,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=6}
as.pop():555,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=5}
as.pop():444,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=4}
as.pop():333,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=3}
as.pop():222,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=2}
as.pop():111,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=1}
as.pop():000,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=0}
as.pop():null,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=0}
as.pop():null,StackBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, count=0}

鏈式棧

使用連結串列來實現棧,push進的資料新增至連結串列的頭結點,pop資料時取的也是連結串列的頭結點,這樣就實現了棧的後進先出。程式碼如下:

public class StackBasedLinkedList implements StackInterface {
    private Node first;

    /**
     * 每次新增資料都向連結串列頭結點新增。
     *
     * @param value
     * @return
     */
    @Override
    public Boolean push(String value) {
        Node newNode = new Node(value, null);
        if (null == first) {
            first = newNode;
        } else {
            newNode.next = first;
            first = newNode;
        }
        return true;
    }

    /**
     * 每次獲取資料都從連結串列頭結點獲取。
     *
     * @return
     */
    @Override
    public String pop() {
        if (null == first) {
            return null;
        } else {
            String tmp = first.getValue();
            first = first.next;
            return tmp;
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        if (first != null) {
            Node curr = first;
            while (curr != null) {
                sb.append(String.valueOf(curr));
                if (curr.next != null) {
                    sb.append(",").append(" ");
                }
                curr = curr.next;
            }
        }
        sb.append("]");
        return sb.toString();
    }

    private static class Node {
        Node next;
        String value;

        public Node(String value, Node next) {
            this.next = next;
            this.value = value;
        }

        public String getValue() {
            return value;
        }

        @Override
        public String toString() {
            return value;
        }
    }
}

測試程式碼:

    StackBasedLinkedList sbll = new StackBasedLinkedList();
    System.out.println(sbll);

    // 新增資料
    for (int i = 0; i < 10; i++) {
        sbll.push("" + i + i + i);
    }
    System.out.println(sbll);

    // 獲取資料
    for (int i = 0; i < 11; i++) {
        System.out.println("sbll.pop():" + sbll.pop());
    }

輸出結果:符合預期。

[]
[999, 888, 777, 666, 555, 444, 333, 222, 111, 000]
sbll.pop():999
sbll.pop():888
sbll.pop():777
sbll.pop():666
sbll.pop():555
sbll.pop():444
sbll.pop():333
sbll.pop():222
sbll.pop():111
sbll.pop():000
sbll.pop():null

完整程式碼請檢視

專案中搜索SingleLinkedList即可。
github傳送門 https://github.com/tinyvampirepudge/DataStructureDemo

gitee傳送門 https://gitee.com/tinytongtong/DataStructureDemo

參考:
如何實現瀏覽器的前進和後退功能?